mirror of
https://github.com/torvalds/linux.git
synced 2026-05-18 03:27:14 +02:00
wifi: iwlwifi: pcie: check for WiAMT/CSME presence
In order to know whether or not a product reset can safely be done (without risking locking up the system completely), check for ME presence with the known methods. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Link: https://patch.msgid.link/20241231135726.0ac9173f1f37.Id83b80b61548b8f4f01e96a356dafe063543c4ac@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
3a0168626c
commit
41fff83fe6
|
|
@ -171,6 +171,7 @@
|
|||
/* NOTE: EEPROM_OWN_SEM is no longer defined for new HW */
|
||||
#define CSR_HW_IF_CONFIG_REG_EEPROM_OWN_SEM 0x00200000
|
||||
#define CSR_HW_IF_CONFIG_REG_PCI_OWN_SET 0x00400000
|
||||
#define CSR_HW_IF_CONFIG_REG_IAMT_UP 0x01000000
|
||||
#define CSR_HW_IF_CONFIG_REG_ME_OWN 0x02000000
|
||||
#define CSR_HW_IF_CONFIG_REG_WAKE_ME 0x08000000
|
||||
#define CSR_HW_IF_CONFIG_REG_WAKE_ME_PCIE_OWNER_EN 0x10000000
|
||||
|
|
|
|||
|
|
@ -381,6 +381,10 @@ enum {
|
|||
#define CNVR_SCU_SD_REGS_SD_REG_ACTIVE_VDIG_MIRROR 0xA29938
|
||||
#define CNVI_SCU_SEQ_DATA_DW9 0xA27488
|
||||
|
||||
#define CNVI_SCU_REG_FOR_ECO_1 0xA26EF8
|
||||
#define CNVI_SCU_REG_FOR_ECO_1_WIAMT_KNOWN BIT(4)
|
||||
#define CNVI_SCU_REG_FOR_ECO_1_WIAMT_PRESENT BIT(5)
|
||||
|
||||
#define CNVI_PMU_STEP_FLOW 0xA2D588
|
||||
#define CNVI_PMU_STEP_FLOW_FORCE_URM BIT(2)
|
||||
|
||||
|
|
|
|||
|
|
@ -882,6 +882,9 @@ struct iwl_txq {
|
|||
* @restart.wk: restart worker
|
||||
* @restart.mode: reset/restart error mode information
|
||||
* @restart.during_reset: error occurred during previous software reset
|
||||
* @me_recheck_wk: worker to recheck WiAMT/CSME presence
|
||||
* @me_present: WiAMT/CSME is detected as present (1), not present (0)
|
||||
* or unknown (-1, so can still use it as a boolean safely)
|
||||
* @trans_specific: data for the specific transport this is allocated for/with
|
||||
* @dsbr_urm_fw_dependent: switch to URM based on fw settings
|
||||
* @dsbr_urm_permanent: switch to URM permanently
|
||||
|
|
@ -960,6 +963,9 @@ struct iwl_trans {
|
|||
bool during_reset;
|
||||
} restart;
|
||||
|
||||
struct delayed_work me_recheck_wk;
|
||||
s8 me_present;
|
||||
|
||||
/* pointer to trans specific struct */
|
||||
/*Ensure that this pointer will always be aligned to sizeof pointer */
|
||||
char trans_specific[] __aligned(sizeof(void *));
|
||||
|
|
|
|||
|
|
@ -1410,6 +1410,47 @@ iwl_pci_find_dev_info(u16 device, u16 subsystem_device,
|
|||
}
|
||||
EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_pci_find_dev_info);
|
||||
|
||||
static void iwl_pcie_recheck_me_status(struct work_struct *wk)
|
||||
{
|
||||
struct iwl_trans *trans = container_of(wk, typeof(*trans),
|
||||
me_recheck_wk.work);
|
||||
u32 val;
|
||||
|
||||
val = iwl_read32(trans, CSR_HW_IF_CONFIG_REG);
|
||||
trans->me_present = !!(val & CSR_HW_IF_CONFIG_REG_IAMT_UP);
|
||||
}
|
||||
|
||||
static void iwl_pcie_check_me_status(struct iwl_trans *trans)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
trans->me_present = -1;
|
||||
|
||||
INIT_DELAYED_WORK(&trans->me_recheck_wk,
|
||||
iwl_pcie_recheck_me_status);
|
||||
|
||||
/* we don't have a good way of determining this until BZ */
|
||||
if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_BZ)
|
||||
return;
|
||||
|
||||
val = iwl_read_prph(trans, CNVI_SCU_REG_FOR_ECO_1);
|
||||
if (val & CNVI_SCU_REG_FOR_ECO_1_WIAMT_KNOWN) {
|
||||
trans->me_present =
|
||||
!!(val & CNVI_SCU_REG_FOR_ECO_1_WIAMT_PRESENT);
|
||||
return;
|
||||
}
|
||||
|
||||
val = iwl_read32(trans, CSR_HW_IF_CONFIG_REG);
|
||||
if (val & (CSR_HW_IF_CONFIG_REG_ME_OWN |
|
||||
CSR_HW_IF_CONFIG_REG_IAMT_UP)) {
|
||||
trans->me_present = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* recheck again later, ME might still be initializing */
|
||||
schedule_delayed_work(&trans->me_recheck_wk, HZ);
|
||||
}
|
||||
|
||||
static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
const struct iwl_cfg_trans_params *trans;
|
||||
|
|
@ -1585,6 +1626,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
|
||||
pci_set_drvdata(pdev, iwl_trans);
|
||||
|
||||
iwl_pcie_check_me_status(iwl_trans);
|
||||
|
||||
/* try to get ownership so that we'll know if we don't own it */
|
||||
iwl_pcie_prepare_card_hw(iwl_trans);
|
||||
|
||||
|
|
@ -1612,6 +1655,8 @@ static void iwl_pci_remove(struct pci_dev *pdev)
|
|||
if (!trans)
|
||||
return;
|
||||
|
||||
cancel_delayed_work_sync(&trans->me_recheck_wk);
|
||||
|
||||
iwl_drv_stop(trans->drv);
|
||||
|
||||
iwl_trans_pcie_free(trans);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user