Commit 44f61b5c authored by Shahar S Matityahu's avatar Shahar S Matityahu Committed by Kalle Valo

iwlwifi: clear persistence bit according to device family

The driver attempts to clear persistence bit on any device familiy even
though only 9000 and 22000 families require it. Clear the bit only on
the relevant device families.

Each HW has different address to the write protection register. Use the
right register for each HW
Signed-off-by: default avatarShahar S Matityahu <shahar.s.matityahu@intel.com>
Fixes: 8954e1eb ("iwlwifi: trans: Clear persistence bit when starting the FW")
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent b3500b47
......@@ -408,7 +408,12 @@ 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
/* device family 9000 WPROT register */
#define PREG_PRPH_WPROT_9000 0xA04CE0
/* device family 22000 WPROT register */
#define PREG_PRPH_WPROT_22000 0xA04D00
#define SB_CPU_1_STATUS 0xA01E30
#define SB_CPU_2_STATUS 0xA01E34
#define UMAG_SB_CPU_1_STATUS 0xA038C0
......
......@@ -1698,26 +1698,26 @@ static int iwl_pcie_init_msix_handler(struct pci_dev *pdev,
return 0;
}
static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power)
static int iwl_trans_pcie_clear_persistence_bit(struct iwl_trans *trans)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
u32 hpm;
int err;
lockdep_assert_held(&trans_pcie->mutex);
u32 hpm, wprot;
err = iwl_pcie_prepare_card_hw(trans);
if (err) {
IWL_ERR(trans, "Error while preparing HW: %d\n", err);
return err;
switch (trans->cfg->device_family) {
case IWL_DEVICE_FAMILY_9000:
wprot = PREG_PRPH_WPROT_9000;
break;
case IWL_DEVICE_FAMILY_22000:
wprot = PREG_PRPH_WPROT_22000;
break;
default:
return 0;
}
hpm = iwl_read_umac_prph_no_grab(trans, HPM_DEBUG);
if (hpm != 0xa5a5a5a0 && (hpm & PERSISTENCE_BIT)) {
int wfpm_val = iwl_read_umac_prph_no_grab(trans,
PREG_PRPH_WPROT_0);
u32 wprot_val = iwl_read_umac_prph_no_grab(trans, wprot);
if (wfpm_val & PREG_WFPM_ACCESS) {
if (wprot_val & PREG_WFPM_ACCESS) {
IWL_ERR(trans,
"Error, can not clear persistence bit\n");
return -EPERM;
......@@ -1726,6 +1726,26 @@ static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power)
hpm & ~PERSISTENCE_BIT);
}
return 0;
}
static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
int err;
lockdep_assert_held(&trans_pcie->mutex);
err = iwl_pcie_prepare_card_hw(trans);
if (err) {
IWL_ERR(trans, "Error while preparing HW: %d\n", err);
return err;
}
err = iwl_trans_pcie_clear_persistence_bit(trans);
if (err)
return err;
iwl_trans_pcie_sw_reset(trans);
err = iwl_pcie_apm_init(trans);
......
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