summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaim Dreyfuss <haim.dreyfuss@intel.com>2015-07-20 14:16:21 +0300
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2015-08-04 10:11:49 +0300
commit869f3b15c9fba037956f642b2023fd16d9ee2f56 (patch)
treeeb550f0b54960d58eebb144e7cec404050494ba1
parentd0ab08d05e5ae84edda5bf86797cbc2daee75db2 (diff)
iwlwifi: pcie: provide a way to stop configuration if it is forbidden
The firmware debug infrastructure allows the user to provide a firmware that will toggle a few registers to configure the debugging capabilities. On certain devices, certain operations are forbidden. Executing a forbidden operation will cause the hardware to die in a way that only driver unload / load will bring it back to life. Fortunately, there is a way to know in advance if those operations will be accepted by the device. This is where the new PRPH_BLOCKBIT operation plays its role. If the bit X from PRPH register Y is set, then we should prevent any further register configuration. When that happens, drop a line in the kernel log since this is really an error state: the user won't have his device configured as he expected. Add operations that will be used in the future: INDIRECT_ASSIGN, INDIRECT_SETBIT, and INDIRECT_CLEARBIT. Other debugging configurations (such as destination configuration for the monitor) will take place in any case. Signed-off-by: Haim Dreyfuss <haim.dreyfuss@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-file.h6
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c9
2 files changed, 15 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
index f99ec4e22052..884825c70533 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
@@ -412,6 +412,12 @@ enum iwl_fw_dbg_reg_operator {
PRPH_ASSIGN,
PRPH_SETBIT,
PRPH_CLEARBIT,
+
+ INDIRECT_ASSIGN,
+ INDIRECT_SETBIT,
+ INDIRECT_CLEARBIT,
+
+ PRPH_BLOCKBIT,
};
/**
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 88ab79fc6249..46e900e860e8 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -881,6 +881,14 @@ static void iwl_pcie_apply_destination(struct iwl_trans *trans)
case PRPH_CLEARBIT:
iwl_clear_bits_prph(trans, addr, BIT(val));
break;
+ case PRPH_BLOCKBIT:
+ if (iwl_read_prph(trans, addr) & BIT(val)) {
+ IWL_ERR(trans,
+ "BIT(%u) in address 0x%x is 1, stopping FW configuration\n",
+ val, addr);
+ goto monitor;
+ }
+ break;
default:
IWL_ERR(trans, "FW debug - unknown OP %d\n",
dest->reg_ops[i].op);
@@ -888,6 +896,7 @@ static void iwl_pcie_apply_destination(struct iwl_trans *trans)
}
}
+monitor:
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);