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

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
...@@ -574,6 +574,9 @@ enum iwl_trans_state { ...@@ -574,6 +574,9 @@ enum iwl_trans_state {
* @rx_mpdu_cmd_hdr_size: used for tracing, amount of data before the * @rx_mpdu_cmd_hdr_size: used for tracing, amount of data before the
* start of the 802.11 header in the @rx_mpdu_cmd * start of the 802.11 header in the @rx_mpdu_cmd
* @dflt_pwr_limit: default power limit fetched from the platform (ACPI) * @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 { struct iwl_trans {
const struct iwl_trans_ops *ops; const struct iwl_trans_ops *ops;
...@@ -605,6 +608,10 @@ struct iwl_trans { ...@@ -605,6 +608,10 @@ struct iwl_trans {
u64 dflt_pwr_limit; 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 */ /* pointer to trans specific struct */
/*Ensure that this pointer will always be aligned to sizeof pointer */ /*Ensure that this pointer will always be aligned to sizeof pointer */
char trans_specific[0] __aligned(sizeof(void *)); char trans_specific[0] __aligned(sizeof(void *));
......
...@@ -496,6 +496,10 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, ...@@ -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 = REPLY_RX_MPDU_CMD;
trans->rx_mpdu_cmd_hdr_size = sizeof(struct iwl_rx_mpdu_res_start); 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 */ /* set up notification wait support */
iwl_notification_wait_init(&mvm->notif_wait); iwl_notification_wait_init(&mvm->notif_wait);
......
...@@ -756,6 +756,64 @@ static int iwl_pcie_load_cpu_sections(struct iwl_trans *trans, ...@@ -756,6 +756,64 @@ static int iwl_pcie_load_cpu_sections(struct iwl_trans *trans,
return 0; 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, static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
const struct fw_img *image) const struct fw_img *image)
{ {
...@@ -796,6 +854,8 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, ...@@ -796,6 +854,8 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
(trans_pcie->fw_mon_phys + (trans_pcie->fw_mon_phys +
trans_pcie->fw_mon_size) >> 4); trans_pcie->fw_mon_size) >> 4);
} }
} else if (trans->dbg_dest_tlv) {
iwl_pcie_apply_destination(trans);
} }
/* release CPU reset */ /* release CPU reset */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment