Received: by 2002:a25:ad19:0:0:0:0:0 with SMTP id y25csp9937737ybi; Wed, 24 Jul 2019 12:39:57 -0700 (PDT) X-Google-Smtp-Source: APXvYqzgyl9KeAhUTRxSXHGc/au1K7uWp1djina953+ii7sNpSfEsVURh97A7diBc4HLAebdE4Qk X-Received: by 2002:a17:902:2bc5:: with SMTP id l63mr90122453plb.30.1563997197710; Wed, 24 Jul 2019 12:39:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1563997197; cv=none; d=google.com; s=arc-20160816; b=MUPiItEiwr6iPKNjauSQNutJs83Z9wgxXNWFiZvHCiTFditb/9djDyZbD2b69roRHK MlvgALyCyAQW3RWbDMiCzoZpAMlqxPUOw4gdEZxSbow8Zs9nGhol0UmtLedLlNY/2BxI HeaOmFANBlPL82Klrzb9+1aH4xKw26Np0qQDiuEAH9aXhfa+hnmZphlh9RuXZhl4Vgax kKHJ9Eu7NF1OBB1CxvcGn0iwNENVBfISGomHtOgpN/vxBfOnlTY9GAOql5e6VPeGluXk 1SalPs675wPXQQ2c7SgVbg5QH1QmHQm55d0b3SeqhVcSh9jJT5VJ2DBaKvSofWsVEecH t9pw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=FG585OMwwxN7ZcARgxax3yGQb3Ace5wcjYs89mVH0FQ=; b=d3jQyivndFUIAMCL0I06G74KhmcfMM67iOWCkBl4dq/UYkipt41EzELs9IUoTxbQDL p879J6UmGAxCv6rRnY0GqSW1PfPgDg78Iu/iJMTt6hyvcrfxLBP9P02CAqJTBP+os/OC 1mCEDwB50ffTVD6wSvVl5w+AoL/eTS7DpCo4ckkPmO2Z+jvGdBvdK3AOXd2ZcFPf15Tu v4irbcIZVrOtKesA7m3ni4LsGrOjdNo0cuhQp9afY4Xw1U3vDzuwkfrnwAxx9jfS+BxH eeGgA3bZA0XfONCb9zPcNlSzl9Rtm08CiodfJ3p2fpVTBt/hwwkJrveYEB1M71f73NFB JyuQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=kwuuK7l0; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w18si13076741pll.132.2019.07.24.12.39.43; Wed, 24 Jul 2019 12:39:57 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=kwuuK7l0; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389783AbfGXTif (ORCPT + 99 others); Wed, 24 Jul 2019 15:38:35 -0400 Received: from mail.kernel.org ([198.145.29.99]:39228 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389775AbfGXTie (ORCPT ); Wed, 24 Jul 2019 15:38:34 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 751D3229F3; Wed, 24 Jul 2019 19:38:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1563997112; bh=wlAdVTuE9GMRYHJXrG6fiieHSf42J+oshFXmwyyYiAw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kwuuK7l0DlghCGzthSFWszf1RIOK8V5CGBKpa0eO2z8OZLG2up1El2Dg3ar0kYnHD GHUKKHaQBW+alxxUtBj8iahy4zSbdgfchAjggeWVEogOQa8mb6KbUMV/kF+Y+2BTwV A17vFOeD7YsSVJ074jK0UDpIzoS/y38enhoMjOIc= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Emmanuel Grumbach , Luca Coelho Subject: [PATCH 5.2 298/413] iwlwifi: fix RF-Kill interrupt while FW load for gen2 devices Date: Wed, 24 Jul 2019 21:19:49 +0200 Message-Id: <20190724191757.348473155@linuxfoundation.org> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190724191735.096702571@linuxfoundation.org> References: <20190724191735.096702571@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Emmanuel Grumbach commit ed3e4c6d3cd8f093a3636cb05492429fe2af228d upstream. Newest devices have a new firmware load mechanism. This mechanism is called the context info. It means that the driver doesn't need to load the sections of the firmware. The driver rather prepares a place in DRAM, with pointers to the relevant sections of the firmware, and the firmware loads itself. At the end of the process, the firmware sends the ALIVE interrupt. This is different from the previous scheme in which the driver expected the FH_TX interrupt after each section being transferred over the DMA. In order to support this new flow, we enabled all the interrupts. This broke the assumption that we have in the code that the RF-Kill interrupt can't interrupt the firmware load flow. Change the context info flow to enable only the ALIVE interrupt, and re-enable all the other interrupts only after the firmware is alive. Then, we won't see the RF-Kill interrupt until then. Getting the RF-Kill interrupt while loading the firmware made us kill the firmware while it is loading and we ended up dumping garbage instead of the firmware state. Re-enable the ALIVE | RX interrupts from the ISR when we get the ALIVE interrupt to be able to get the RX interrupt that comes immediately afterwards for the ALIVE notification. This is needed for non MSI-X only. Cc: stable@vger.kernel.org Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c | 2 - drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c | 2 - drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 27 +++++++++++++++ drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 5 ++ drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c | 9 +++++ 5 files changed, 43 insertions(+), 2 deletions(-) --- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c @@ -169,7 +169,7 @@ int iwl_pcie_ctxt_info_gen3_init(struct memcpy(iml_img, trans->iml, trans->iml_len); - iwl_enable_interrupts(trans); + iwl_enable_fw_load_int_ctx_info(trans); /* kick FW self load */ iwl_write64(trans, CSR_CTXT_INFO_ADDR, --- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c @@ -222,7 +222,7 @@ int iwl_pcie_ctxt_info_init(struct iwl_t trans_pcie->ctxt_info = ctxt_info; - iwl_enable_interrupts(trans); + iwl_enable_fw_load_int_ctx_info(trans); /* Configure debug, if exists */ if (iwl_pcie_dbg_on(trans)) --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -874,6 +874,33 @@ static inline void iwl_enable_fw_load_in } } +static inline void iwl_enable_fw_load_int_ctx_info(struct iwl_trans *trans) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + + IWL_DEBUG_ISR(trans, "Enabling ALIVE interrupt only\n"); + + if (!trans_pcie->msix_enabled) { + /* + * When we'll receive the ALIVE interrupt, the ISR will call + * iwl_enable_fw_load_int_ctx_info again to set the ALIVE + * interrupt (which is not really needed anymore) but also the + * RX interrupt which will allow us to receive the ALIVE + * notification (which is Rx) and continue the flow. + */ + trans_pcie->inta_mask = CSR_INT_BIT_ALIVE | CSR_INT_BIT_FH_RX; + iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask); + } else { + iwl_enable_hw_int_msk_msix(trans, + MSIX_HW_INT_CAUSES_REG_ALIVE); + /* + * Leave all the FH causes enabled to get the ALIVE + * notification. + */ + iwl_enable_fh_int_msk_msix(trans, trans_pcie->fh_init_mask); + } +} + static inline u16 iwl_pcie_get_cmd_index(const struct iwl_txq *q, u32 index) { return index & (q->n_window - 1); --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -1845,6 +1845,8 @@ irqreturn_t iwl_pcie_irq_handler(int irq */ iwl_pcie_rxmq_restock(trans, trans_pcie->rxq); } + + handled |= CSR_INT_BIT_ALIVE; } /* Safely ignore these bits for debug checks below */ @@ -1963,6 +1965,9 @@ irqreturn_t iwl_pcie_irq_handler(int irq /* Re-enable RF_KILL if it occurred */ else if (handled & CSR_INT_BIT_RF_KILL) iwl_enable_rfkill_int(trans); + /* Re-enable the ALIVE / Rx interrupt if it occurred */ + else if (handled & (CSR_INT_BIT_ALIVE | CSR_INT_BIT_FH_RX)) + iwl_enable_fw_load_int_ctx_info(trans); spin_unlock(&trans_pcie->irq_lock); out: --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c @@ -273,6 +273,15 @@ void iwl_trans_pcie_gen2_fw_alive(struct * paging memory cannot be freed included since FW will still use it */ iwl_pcie_ctxt_info_free(trans); + + /* + * Re-enable all the interrupts, including the RF-Kill one, now that + * the firmware is alive. + */ + iwl_enable_interrupts(trans); + mutex_lock(&trans_pcie->mutex); + iwl_pcie_check_hw_rf_kill(trans); + mutex_unlock(&trans_pcie->mutex); } int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans,