Commit 869f3b15 authored by Haim Dreyfuss's avatar Haim Dreyfuss Committed by Emmanuel Grumbach

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: default avatarHaim Dreyfuss <haim.dreyfuss@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent d0ab08d0
...@@ -412,6 +412,12 @@ enum iwl_fw_dbg_reg_operator { ...@@ -412,6 +412,12 @@ enum iwl_fw_dbg_reg_operator {
PRPH_ASSIGN, PRPH_ASSIGN,
PRPH_SETBIT, PRPH_SETBIT,
PRPH_CLEARBIT, PRPH_CLEARBIT,
INDIRECT_ASSIGN,
INDIRECT_SETBIT,
INDIRECT_CLEARBIT,
PRPH_BLOCKBIT,
}; };
/** /**
......
...@@ -881,6 +881,14 @@ static void iwl_pcie_apply_destination(struct iwl_trans *trans) ...@@ -881,6 +881,14 @@ static void iwl_pcie_apply_destination(struct iwl_trans *trans)
case PRPH_CLEARBIT: case PRPH_CLEARBIT:
iwl_clear_bits_prph(trans, addr, BIT(val)); iwl_clear_bits_prph(trans, addr, BIT(val));
break; 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: default:
IWL_ERR(trans, "FW debug - unknown OP %d\n", IWL_ERR(trans, "FW debug - unknown OP %d\n",
dest->reg_ops[i].op); dest->reg_ops[i].op);
...@@ -888,6 +896,7 @@ static void iwl_pcie_apply_destination(struct iwl_trans *trans) ...@@ -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) { if (dest->monitor_mode == EXTERNAL_MODE && trans_pcie->fw_mon_size) {
iwl_write_prph(trans, le32_to_cpu(dest->base_reg), iwl_write_prph(trans, le32_to_cpu(dest->base_reg),
trans_pcie->fw_mon_phys >> dest->base_shift); trans_pcie->fw_mon_phys >> dest->base_shift);
......
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