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

Commit 12d56175 authored by Kalle Valo's avatar Kalle Valo
Browse files

Merge tag 'iwlwifi-next-for-kalle-2018-11-11' of...

Merge tag 'iwlwifi-next-for-kalle-2018-11-11' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next

First set of iwlwifi patches for 4.21

* PCI IDs for some new 9000-series cards;
* Improve antenna usage on connection problems;
* Some improvements in the debugging code;
* Other clean-ups and small fixes;
parents bb38177c 56b657f7
Loading
Loading
Loading
Loading
+54 −55
Original line number Diff line number Diff line
@@ -240,7 +240,7 @@ static void iwl_fw_dump_fifos(struct iwl_fw_runtime *fwrt,
	if (!iwl_trans_grab_nic_access(fwrt->trans, &flags))
		return;

	if (fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_RXF)) {
	if (iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_RXF)) {
		/* Pull RXF1 */
		iwl_fwrt_dump_rxf(fwrt, dump_data,
				  cfg->lmac[0].rxfifo1_size, 0, 0);
@@ -254,7 +254,7 @@ static void iwl_fw_dump_fifos(struct iwl_fw_runtime *fwrt,
					  LMAC2_PRPH_OFFSET, 2);
	}

	if (fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_TXF)) {
	if (iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_TXF)) {
		/* Pull TXF data from LMAC1 */
		for (i = 0; i < fwrt->smem_cfg.num_txfifo_entries; i++) {
			/* Mark the number of TXF we're pulling now */
@@ -279,7 +279,7 @@ static void iwl_fw_dump_fifos(struct iwl_fw_runtime *fwrt,
		}
	}

	if (fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_INTERNAL_TXF) &&
	if (iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_INTERNAL_TXF) &&
	    fw_has_capa(&fwrt->fw->ucode_capa,
			IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG)) {
		/* Pull UMAC internal TXF data from all TXFs */
@@ -603,7 +603,7 @@ static int iwl_fw_fifo_len(struct iwl_fw_runtime *fwrt,
	u32 fifo_len = 0;
	int i;

	if (!(fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_RXF)))
	if (!iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_RXF))
		goto dump_txf;

	/* Count RXF2 size */
@@ -614,7 +614,7 @@ static int iwl_fw_fifo_len(struct iwl_fw_runtime *fwrt,
		ADD_LEN(fifo_len, mem_cfg->lmac[i].rxfifo1_size, hdr_len);

dump_txf:
	if (!(fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_TXF)))
	if (!iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_TXF))
		goto dump_internal_txf;

	/* Count TXF sizes */
@@ -627,7 +627,7 @@ static int iwl_fw_fifo_len(struct iwl_fw_runtime *fwrt,
	}

dump_internal_txf:
	if (!((fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_INTERNAL_TXF)) &&
	if (!(iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_INTERNAL_TXF) &&
	      fw_has_capa(&fwrt->fw->ucode_capa,
			  IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG)))
		goto out;
@@ -639,6 +639,32 @@ static int iwl_fw_fifo_len(struct iwl_fw_runtime *fwrt,
	return fifo_len;
}

static void iwl_dump_paging(struct iwl_fw_runtime *fwrt,
			    struct iwl_fw_error_dump_data **data)
{
	int i;

	IWL_DEBUG_INFO(fwrt, "WRT paging dump\n");
	for (i = 1; i < fwrt->num_of_paging_blk + 1; i++) {
		struct iwl_fw_error_dump_paging *paging;
		struct page *pages =
			fwrt->fw_paging_db[i].fw_paging_block;
		dma_addr_t addr = fwrt->fw_paging_db[i].fw_paging_phys;

		(*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_PAGING);
		(*data)->len = cpu_to_le32(sizeof(*paging) +
					     PAGING_BLOCK_SIZE);
		paging =  (void *)(*data)->data;
		paging->index = cpu_to_le32(i);
		dma_sync_single_for_cpu(fwrt->trans->dev, addr,
					PAGING_BLOCK_SIZE,
					DMA_BIDIRECTIONAL);
		memcpy(paging->data, page_address(pages),
		       PAGING_BLOCK_SIZE);
		(*data) = iwl_fw_error_next_data(*data);
	}
}

static struct iwl_fw_error_dump_file *
_iwl_fw_error_dump(struct iwl_fw_runtime *fwrt,
		   struct iwl_fw_dump_ptrs *fw_error_dump)
@@ -655,13 +681,8 @@ _iwl_fw_error_dump(struct iwl_fw_runtime *fwrt,
	u32 smem_len = fwrt->fw->dbg.n_mem_tlv ? 0 : fwrt->trans->cfg->smem_len;
	u32 sram2_len = fwrt->fw->dbg.n_mem_tlv ?
				0 : fwrt->trans->cfg->dccm2_len;
	bool monitor_dump_only = false;
	int i;

	if (fwrt->dump.trig &&
	    fwrt->dump.trig->mode & IWL_FW_DBG_TRIGGER_MONITOR_ONLY)
		monitor_dump_only = true;

	/* SRAM - include stack CCM if driver knows the values for it */
	if (!fwrt->trans->cfg->dccm_offset || !fwrt->trans->cfg->dccm_len) {
		const struct fw_img *img;
@@ -680,22 +701,22 @@ _iwl_fw_error_dump(struct iwl_fw_runtime *fwrt,

		/* Make room for PRPH registers */
		if (!fwrt->trans->cfg->gen2 &&
		    fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_PRPH))
		   iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_PRPH))
			prph_len += iwl_fw_get_prph_len(fwrt);

		if (fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_7000 &&
		    fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_RADIO_REG))
		    iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_RADIO_REG))
			radio_len = sizeof(*dump_data) + RADIO_REG_MAX_READ;
	}

	file_len = sizeof(*dump_file) + fifo_len + prph_len + radio_len;

	if (fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_DEV_FW_INFO))
	if (iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_DEV_FW_INFO))
		file_len += sizeof(*dump_data) + sizeof(*dump_info);
	if (fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_MEM_CFG))
	if (iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_MEM_CFG))
		file_len += sizeof(*dump_data) + sizeof(*dump_smem_cfg);

	if (fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_MEM)) {
	if (iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_MEM)) {
		size_t hdr_len = sizeof(*dump_data) +
				 sizeof(struct iwl_fw_error_dump_mem);

@@ -712,10 +733,7 @@ _iwl_fw_error_dump(struct iwl_fw_runtime *fwrt,
	}

	/* Make room for fw's virtual image pages, if it exists */
	if (fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING) &&
	    !fwrt->trans->cfg->gen2 &&
	    fwrt->fw->img[fwrt->cur_fw_img].paging_mem_size &&
	    fwrt->fw_paging_db[0].fw_paging_block)
	if (iwl_fw_dbg_is_paging_enabled(fwrt))
		file_len += fwrt->num_of_paging_blk *
			(sizeof(*dump_data) +
			 sizeof(struct iwl_fw_error_dump_paging) +
@@ -727,12 +745,12 @@ _iwl_fw_error_dump(struct iwl_fw_runtime *fwrt,
	}

	/* If we only want a monitor dump, reset the file length */
	if (monitor_dump_only) {
	if (fwrt->dump.monitor_only) {
		file_len = sizeof(*dump_file) + sizeof(*dump_data) * 2 +
			   sizeof(*dump_info) + sizeof(*dump_smem_cfg);
	}

	if (fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_ERROR_INFO) &&
	if (iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_ERROR_INFO) &&
	    fwrt->dump.desc)
		file_len += sizeof(*dump_data) + sizeof(*dump_trig) +
			    fwrt->dump.desc->len;
@@ -746,7 +764,7 @@ _iwl_fw_error_dump(struct iwl_fw_runtime *fwrt,
	dump_file->barker = cpu_to_le32(IWL_FW_ERROR_DUMP_BARKER);
	dump_data = (void *)dump_file->data;

	if (fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_DEV_FW_INFO)) {
	if (iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_DEV_FW_INFO)) {
		dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_DEV_FW_INFO);
		dump_data->len = cpu_to_le32(sizeof(*dump_info));
		dump_info = (void *)dump_data->data;
@@ -767,7 +785,7 @@ _iwl_fw_error_dump(struct iwl_fw_runtime *fwrt,
		dump_data = iwl_fw_error_next_data(dump_data);
	}

	if (fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_MEM_CFG)) {
	if (iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_MEM_CFG)) {
		/* Dump shared memory configuration */
		dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_CFG);
		dump_data->len = cpu_to_le32(sizeof(*dump_smem_cfg));
@@ -804,7 +822,7 @@ _iwl_fw_error_dump(struct iwl_fw_runtime *fwrt,
			iwl_read_radio_regs(fwrt, &dump_data);
	}

	if (fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_ERROR_INFO) &&
	if (iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_ERROR_INFO) &&
	    fwrt->dump.desc) {
		dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_ERROR_INFO);
		dump_data->len = cpu_to_le32(sizeof(*dump_trig) +
@@ -817,10 +835,10 @@ _iwl_fw_error_dump(struct iwl_fw_runtime *fwrt,
	}

	/* In case we only want monitor dump, skip to dump trasport data */
	if (monitor_dump_only)
	if (fwrt->dump.monitor_only)
		goto out;

	if (fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_MEM)) {
	if (iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_MEM)) {
		const struct iwl_fw_dbg_mem_seg_tlv *fw_dbg_mem =
			fwrt->fw->dbg.mem_tlv;

@@ -865,30 +883,8 @@ _iwl_fw_error_dump(struct iwl_fw_runtime *fwrt,
	}

	/* Dump fw's virtual image */
	if (fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING) &&
	    !fwrt->trans->cfg->gen2 &&
	    fwrt->fw->img[fwrt->cur_fw_img].paging_mem_size &&
	    fwrt->fw_paging_db[0].fw_paging_block) {
		IWL_DEBUG_INFO(fwrt, "WRT paging dump\n");
		for (i = 1; i < fwrt->num_of_paging_blk + 1; i++) {
			struct iwl_fw_error_dump_paging *paging;
			struct page *pages =
				fwrt->fw_paging_db[i].fw_paging_block;
			dma_addr_t addr = fwrt->fw_paging_db[i].fw_paging_phys;

			dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_PAGING);
			dump_data->len = cpu_to_le32(sizeof(*paging) +
						     PAGING_BLOCK_SIZE);
			paging = (void *)dump_data->data;
			paging->index = cpu_to_le32(i);
			dma_sync_single_for_cpu(fwrt->trans->dev, addr,
						PAGING_BLOCK_SIZE,
						DMA_BIDIRECTIONAL);
			memcpy(paging->data, page_address(pages),
			       PAGING_BLOCK_SIZE);
			dump_data = iwl_fw_error_next_data(dump_data);
		}
	}
	if (iwl_fw_dbg_is_paging_enabled(fwrt))
		iwl_dump_paging(fwrt, &dump_data);

	if (prph_len) {
		iwl_dump_prph(fwrt->trans, &dump_data,
@@ -932,7 +928,7 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
	}

	fw_error_dump->trans_ptr = iwl_trans_dump_data(fwrt->trans,
						       fwrt->dump.trig);
						       fwrt->dump.monitor_only);
	file_len = le32_to_cpu(dump_file->file_len);
	fw_error_dump->fwrt_len = file_len;
	if (fw_error_dump->trans_ptr) {
@@ -998,7 +994,8 @@ void iwl_fw_alive_error_dump(struct iwl_fw_runtime *fwrt)
IWL_EXPORT_SYMBOL(iwl_fw_alive_error_dump);

int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
			    const struct iwl_fw_dump_desc *desc, void *trigger,
			    const struct iwl_fw_dump_desc *desc,
			    bool monitor_only,
			    unsigned int delay)
{
	/*
@@ -1028,7 +1025,7 @@ int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
		 le32_to_cpu(desc->trig_desc.type));

	fwrt->dump.desc = desc;
	fwrt->dump.trig = trigger;
	fwrt->dump.monitor_only = monitor_only;

	schedule_delayed_work(&fwrt->dump.wk, delay);

@@ -1043,6 +1040,7 @@ int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
{
	struct iwl_fw_dump_desc *desc;
	unsigned int delay = 0;
	bool monitor_only = false;

	if (trigger) {
		u16 occurrences = le16_to_cpu(trigger->occurrences) - 1;
@@ -1059,6 +1057,7 @@ int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,

		trigger->occurrences = cpu_to_le16(occurrences);
		delay = le16_to_cpu(trigger->trig_dis_ms);
		monitor_only = trigger->mode & IWL_FW_DBG_TRIGGER_MONITOR_ONLY;
	}

	desc = kzalloc(sizeof(*desc) + len, GFP_ATOMIC);
@@ -1070,7 +1069,7 @@ int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
	desc->trig_desc.type = cpu_to_le32(trig);
	memcpy(desc->trig_desc.data, str, len);

	return iwl_fw_dbg_collect_desc(fwrt, desc, trigger, delay);
	return iwl_fw_dbg_collect_desc(fwrt, desc, monitor_only, delay);
}
IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect);

+15 −3
Original line number Diff line number Diff line
@@ -101,13 +101,12 @@ static inline void iwl_fw_free_dump_desc(struct iwl_fw_runtime *fwrt)
	if (fwrt->dump.desc != &iwl_dump_desc_assert)
		kfree(fwrt->dump.desc);
	fwrt->dump.desc = NULL;
	fwrt->dump.trig = NULL;
}

void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt);
int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
			    const struct iwl_fw_dump_desc *desc,
			    void *trigger, unsigned int delay);
			    bool monitor_only, unsigned int delay);
int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
		       enum iwl_fw_dbg_trigger trig,
		       const char *str, size_t len,
@@ -310,12 +309,25 @@ static inline void iwl_fw_dump_conf_clear(struct iwl_fw_runtime *fwrt)

void iwl_fw_error_dump_wk(struct work_struct *work);

static inline bool iwl_fw_dbg_type_on(struct iwl_fw_runtime *fwrt, u32 type)
{
	return (fwrt->fw->dbg.dump_mask & BIT(type));
}

static inline bool iwl_fw_dbg_is_d3_debug_enabled(struct iwl_fw_runtime *fwrt)
{
	return fw_has_capa(&fwrt->fw->ucode_capa,
			   IWL_UCODE_TLV_CAPA_D3_DEBUG) &&
		fwrt->trans->cfg->d3_debug_data_length &&
		fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_D3_DEBUG_DATA);
		iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_D3_DEBUG_DATA);
}

static inline bool iwl_fw_dbg_is_paging_enabled(struct iwl_fw_runtime *fwrt)
{
	return iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_PAGING) &&
		!fwrt->trans->cfg->gen2 &&
		fwrt->fw->img[fwrt->cur_fw_img].paging_mem_size &&
		fwrt->fw_paging_db[0].fw_paging_block;
}

void iwl_fw_dbg_read_d3_debug_data(struct iwl_fw_runtime *fwrt);
+1 −1
Original line number Diff line number Diff line
@@ -131,7 +131,7 @@ struct iwl_fw_runtime {
	/* debug */
	struct {
		const struct iwl_fw_dump_desc *desc;
		const struct iwl_fw_dbg_trigger_tlv *trig;
		bool monitor_only;
		struct delayed_work wk;

		u8 conf;
+7 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
 * Copyright(c) 2016        Intel Deutschland GmbH
 * Copyright (C) 2018 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
@@ -30,6 +31,7 @@
 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
 * Copyright(c) 2016        Intel Deutschland GmbH
 * Copyright (C) 2018 Intel Corporation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -394,6 +396,7 @@ enum aux_misc_master1_en {
#define AUX_MISC_MASTER1_SMPHR_STATUS	0xA20800
#define RSA_ENABLE			0xA24B08
#define PREG_AUX_BUS_WPROT_0		0xA04CC0
#define PREG_PRPH_WPROT_0		0xA04CE0
#define SB_CPU_1_STATUS			0xA01E30
#define SB_CPU_2_STATUS			0xA01E34
#define UMAG_SB_CPU_1_STATUS		0xA038C0
@@ -420,4 +423,8 @@ enum {
#define UREG_CHICK		(0xA05C00)
#define UREG_CHICK_MSI_ENABLE	BIT(24)
#define UREG_CHICK_MSIX_ENABLE	BIT(25)

#define HPM_DEBUG			0xA03440
#define PERSISTENCE_BIT			BIT(12)
#define PREG_WFPM_ACCESS		BIT(12)
#endif				/* __iwl_prph_h__ */
+3 −5
Original line number Diff line number Diff line
@@ -602,8 +602,7 @@ struct iwl_trans_ops {
	void (*resume)(struct iwl_trans *trans);

	struct iwl_trans_dump_data *(*dump_data)(struct iwl_trans *trans,
						 const struct iwl_fw_dbg_trigger_tlv
						 *trigger);
						 bool monitor_only);
};

/**
@@ -897,12 +896,11 @@ static inline void iwl_trans_resume(struct iwl_trans *trans)
}

static inline struct iwl_trans_dump_data *
iwl_trans_dump_data(struct iwl_trans *trans,
		    const struct iwl_fw_dbg_trigger_tlv *trigger)
iwl_trans_dump_data(struct iwl_trans *trans, bool monitor_only)
{
	if (!trans->ops->dump_data)
		return NULL;
	return trans->ops->dump_data(trans, trigger);
	return trans->ops->dump_data(trans, monitor_only);
}

static inline struct iwl_device_cmd *
Loading