From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-sn1nam02on0123.outbound.protection.outlook.com ([104.47.36.123]:20160 "EHLO NAM02-SN1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727741AbeIBRTy (ORCPT ); Sun, 2 Sep 2018 13:19:54 -0400 From: Sasha Levin To: "stable@vger.kernel.org" , "linux-kernel@vger.kernel.org" CC: Emmanuel Grumbach , Luca Coelho , Sasha Levin Subject: [PATCH AUTOSEL 4.18 034/131] iwlwifi: pcie: don't access periphery registers when not available Date: Sun, 2 Sep 2018 13:03:40 +0000 Message-ID: <20180902064601.183036-34-alexander.levin@microsoft.com> References: <20180902064601.183036-1-alexander.levin@microsoft.com> In-Reply-To: <20180902064601.183036-1-alexander.levin@microsoft.com> Content-Language: en-US Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Sender: stable-owner@vger.kernel.org List-ID: From: Emmanuel Grumbach [ Upstream commit f98ad635c097c29339b7a7d6947173000485893d ] The periphery can't be accessed before we set the INIT_DONE bit which initializes the device. A previous patch added a reconfiguration of the MSI-X tables upon resume, but at that point in the flow, INIT_DONE wasn't set. Since the reconfiguration of the MSI-X tables require periphery access, it failed. The difference between WoWLAN and without WoWLAN is that in WoWLAN, iwl_trans_pcie_d3_suspend clears the INIT_DONE without clearing the STATUS_DEVICE_ENABLED bit in the software status. Because of that, the resume code thinks that the device is enabled, but the INIT_DONE bit has been cleared. To fix this, don't reconfigure the MSI-X tables in case WoWLAN is enabled. It will be done in iwl_trans_pcie_d3_resume anyway. Fixes: 52848a79b9d2 ("iwlwifi: pcie: reconfigure MSI-X HW on resume") Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho Signed-off-by: Sasha Levin --- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 4 ++++ .../net/wireless/intel/iwlwifi/pcie/trans.c | 24 +++++++++---------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wi= reless/intel/iwlwifi/pcie/drv.c index 8520523b91b4..d8d8443c1c93 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -1003,6 +1003,10 @@ static int iwl_pci_resume(struct device *device) if (!trans->op_mode) return 0; =20 + /* In WOWLAN, let iwl_trans_pcie_d3_resume do the rest of the work */ + if (test_bit(STATUS_DEVICE_ENABLED, &trans->status)) + return 0; + /* reconfigure the MSI-X mapping to get the correct IRQ for rfkill */ iwl_pcie_conf_msix_hw(trans_pcie); =20 diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/= wireless/intel/iwlwifi/pcie/trans.c index 7229991ae70d..a2a98087eb41 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -1539,18 +1539,6 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans= *trans, =20 iwl_pcie_enable_rx_wake(trans, true); =20 - /* - * Reconfigure IVAR table in case of MSIX or reset ict table in - * MSI mode since HW reset erased it. - * Also enables interrupts - none will happen as - * the device doesn't know we're waking it up, only when - * the opmode actually tells it after this call. - */ - iwl_pcie_conf_msix_hw(trans_pcie); - if (!trans_pcie->msix_enabled) - iwl_pcie_reset_ict(trans); - iwl_enable_interrupts(trans); - iwl_set_bit(trans, CSR_GP_CNTRL, BIT(trans->cfg->csr->flag_mac_access_req)); iwl_set_bit(trans, CSR_GP_CNTRL, @@ -1568,6 +1556,18 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans= *trans, return ret; } =20 + /* + * Reconfigure IVAR table in case of MSIX or reset ict table in + * MSI mode since HW reset erased it. + * Also enables interrupts - none will happen as + * the device doesn't know we're waking it up, only when + * the opmode actually tells it after this call. + */ + iwl_pcie_conf_msix_hw(trans_pcie); + if (!trans_pcie->msix_enabled) + iwl_pcie_reset_ict(trans); + iwl_enable_interrupts(trans); + iwl_pcie_set_pwr(trans, false); =20 if (!reset) { --=20 2.17.1