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

Commit 09e350f7 authored by Liad Kaufman's avatar Liad Kaufman Committed by Emmanuel Grumbach
Browse files

iwlwifi: pcie: config regs according to fw tlv



Sometimes there is a need to configure some registers for
setting some FW properties, such as the FW monitor mode
(internal/external). This patch supports setting this for
PCIe mode.

Signed-off-by: default avatarLiad Kaufman <liad.kaufman@intel.com>
Reviewed-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent 6a951267
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -574,6 +574,9 @@ enum iwl_trans_state {
 * @rx_mpdu_cmd_hdr_size: used for tracing, amount of data before the
 *	start of the 802.11 header in the @rx_mpdu_cmd
 * @dflt_pwr_limit: default power limit fetched from the platform (ACPI)
 * @dbg_dest_tlv: points to the destination TLV for debug
 * @dbg_conf_tlv: array of pointers to configuration TLVs for debug
 * @dbg_dest_reg_num: num of reg_ops in %dbg_dest_tlv
 */
struct iwl_trans {
	const struct iwl_trans_ops *ops;
@@ -605,6 +608,10 @@ struct iwl_trans {

	u64 dflt_pwr_limit;

	const struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv;
	const struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_MAX];
	u8 dbg_dest_reg_num;

	/* pointer to trans specific struct */
	/*Ensure that this pointer will always be aligned to sizeof pointer */
	char trans_specific[0] __aligned(sizeof(void *));
+4 −0
Original line number Diff line number Diff line
@@ -496,6 +496,10 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,

	trans->rx_mpdu_cmd = REPLY_RX_MPDU_CMD;
	trans->rx_mpdu_cmd_hdr_size = sizeof(struct iwl_rx_mpdu_res_start);
	trans->dbg_dest_tlv = mvm->fw->dbg_dest_tlv;
	trans->dbg_dest_reg_num = mvm->fw->dbg_dest_reg_num;
	memcpy(trans->dbg_conf_tlv, mvm->fw->dbg_conf_tlv,
	       sizeof(trans->dbg_conf_tlv));

	/* set up notification wait support */
	iwl_notification_wait_init(&mvm->notif_wait);
+60 −0
Original line number Diff line number Diff line
@@ -756,6 +756,64 @@ static int iwl_pcie_load_cpu_sections(struct iwl_trans *trans,
	return 0;
}

static void iwl_pcie_apply_destination(struct iwl_trans *trans)
{
	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
	const struct iwl_fw_dbg_dest_tlv *dest = trans->dbg_dest_tlv;
	int i;

	if (dest->version)
		IWL_ERR(trans,
			"DBG DEST version is %d - expect issues\n",
			dest->version);

	IWL_INFO(trans, "Applying debug destination %s\n",
		 get_fw_dbg_mode_string(dest->monitor_mode));

	if (dest->monitor_mode == EXTERNAL_MODE)
		iwl_pcie_alloc_fw_monitor(trans);
	else
		IWL_WARN(trans, "PCI should have external buffer debug\n");

	for (i = 0; i < trans->dbg_dest_reg_num; i++) {
		u32 addr = le32_to_cpu(dest->reg_ops[i].addr);
		u32 val = le32_to_cpu(dest->reg_ops[i].val);

		switch (dest->reg_ops[i].op) {
		case CSR_ASSIGN:
			iwl_write32(trans, addr, val);
			break;
		case CSR_SETBIT:
			iwl_set_bit(trans, addr, BIT(val));
			break;
		case CSR_CLEARBIT:
			iwl_clear_bit(trans, addr, BIT(val));
			break;
		case PRPH_ASSIGN:
			iwl_write_prph(trans, addr, val);
			break;
		case PRPH_SETBIT:
			iwl_set_bits_prph(trans, addr, BIT(val));
			break;
		case PRPH_CLEARBIT:
			iwl_clear_bits_prph(trans, addr, BIT(val));
			break;
		default:
			IWL_ERR(trans, "FW debug - unknown OP %d\n",
				dest->reg_ops[i].op);
			break;
		}
	}

	if (dest->monitor_mode == EXTERNAL_MODE && trans_pcie->fw_mon_size) {
		iwl_write_prph(trans, le32_to_cpu(dest->base_reg),
			       trans_pcie->fw_mon_phys >> dest->base_shift);
		iwl_write_prph(trans, le32_to_cpu(dest->end_reg),
			       (trans_pcie->fw_mon_phys +
				trans_pcie->fw_mon_size) >> dest->end_shift);
	}
}

static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
				const struct fw_img *image)
{
@@ -796,6 +854,8 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
				       (trans_pcie->fw_mon_phys +
					trans_pcie->fw_mon_size) >> 4);
		}
	} else if (trans->dbg_dest_tlv) {
		iwl_pcie_apply_destination(trans);
	}

	/* release CPU reset */