From: Sasha Levin <sashal@kernel.org> To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Emmanuel Grumbach <emmanuel.grumbach@intel.com>, Luca Coelho <luciano.coelho@intel.com>, Kalle Valo <kvalo@codeaurora.org>, Sasha Levin <sashal@kernel.org>, linux-wireless@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH AUTOSEL 5.1 25/95] iwlwifi: fix load in rfkill flow for unified firmware Date: Wed, 26 Jun 2019 20:29:10 -0400 Message-ID: <20190627003021.19867-25-sashal@kernel.org> (raw) In-Reply-To: <20190627003021.19867-1-sashal@kernel.org> From: Emmanuel Grumbach <emmanuel.grumbach@intel.com> [ Upstream commit b3500b472c880b5abe90ffd5c4a25aa736f906ad ] When we have a single image (same firmware image for INIT and OPERATIONAL), we couldn't load the driver and register to the stack if we had hardware RF-Kill asserted. Fix this. This required a few changes: 1) Run the firmware as part of the INIT phase even if its ucode_type is not IWL_UCODE_INIT. 2) Send the commands that are sent to the unified image in INIT flow even in RF-Kill. 3) Don't ask the transport to stop the hardware upon RF-Kill interrupt if the RF-Kill is asserted. 4) Allow the RF-Kill interrupt to take us out of L1A so that the RF-Kill interrupt will be received by the host (to enable the radio). Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org> Signed-off-by: Sasha Levin <sashal@kernel.org> --- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 23 ++++++++++++++----- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 17 ++++++++++---- .../wireless/intel/iwlwifi/pcie/internal.h | 2 +- 5 files changed, 33 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index ab68b5d53ec9..153717587aeb 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -311,6 +311,8 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, int ret; enum iwl_ucode_type old_type = mvm->fwrt.cur_fw_img; static const u16 alive_cmd[] = { MVM_ALIVE }; + bool run_in_rfkill = + ucode_type == IWL_UCODE_INIT || iwl_mvm_has_unified_ucode(mvm); if (ucode_type == IWL_UCODE_REGULAR && iwl_fw_dbg_conf_usniffer(mvm->fw, FW_DBG_START_FROM_ALIVE) && @@ -328,7 +330,12 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, alive_cmd, ARRAY_SIZE(alive_cmd), iwl_alive_fn, &alive_data); - ret = iwl_trans_start_fw(mvm->trans, fw, ucode_type == IWL_UCODE_INIT); + /* + * We want to load the INIT firmware even in RFKILL + * For the unified firmware case, the ucode_type is not + * INIT, but we still need to run it. + */ + ret = iwl_trans_start_fw(mvm->trans, fw, run_in_rfkill); if (ret) { iwl_fw_set_current_image(&mvm->fwrt, old_type); iwl_remove_notification(&mvm->notif_wait, &alive_wait); @@ -433,7 +440,8 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) * commands */ ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(SYSTEM_GROUP, - INIT_EXTENDED_CFG_CMD), 0, + INIT_EXTENDED_CFG_CMD), + CMD_SEND_IN_RFKILL, sizeof(init_cfg), &init_cfg); if (ret) { IWL_ERR(mvm, "Failed to run init config command: %d\n", @@ -457,7 +465,8 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) } ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(REGULATORY_AND_NVM_GROUP, - NVM_ACCESS_COMPLETE), 0, + NVM_ACCESS_COMPLETE), + CMD_SEND_IN_RFKILL, sizeof(nvm_complete), &nvm_complete); if (ret) { IWL_ERR(mvm, "Failed to run complete NVM access: %d\n", @@ -482,6 +491,8 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) } } + mvm->rfkill_safe_init_done = true; + return 0; error: @@ -526,7 +537,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) lockdep_assert_held(&mvm->mutex); - if (WARN_ON_ONCE(mvm->calibrating)) + if (WARN_ON_ONCE(mvm->rfkill_safe_init_done)) return 0; iwl_init_notification_wait(&mvm->notif_wait, @@ -576,7 +587,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) goto remove_notif; } - mvm->calibrating = true; + mvm->rfkill_safe_init_done = true; /* Send TX valid antennas before triggering calibrations */ ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm)); @@ -612,7 +623,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) remove_notif: iwl_remove_notification(&mvm->notif_wait, &calib_wait); out: - mvm->calibrating = false; + mvm->rfkill_safe_init_done = false; if (iwlmvm_mod_params.init_dbg && !mvm->nvm_data) { /* we want to debug INIT and we have no NVM - fake */ mvm->nvm_data = kzalloc(sizeof(struct iwl_nvm_data) + diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 6a3b11dd2edf..4ddf620c267d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1211,7 +1211,7 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) mvm->scan_status = 0; mvm->ps_disabled = false; - mvm->calibrating = false; + mvm->rfkill_safe_init_done = false; /* just in case one was running */ iwl_mvm_cleanup_roc_te(mvm); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index a50dc53df086..b698d55ace1b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -877,7 +877,7 @@ struct iwl_mvm { struct iwl_mvm_vif *bf_allowed_vif; bool hw_registered; - bool calibrating; + bool rfkill_safe_init_done; bool support_umac_log; u32 ampdu_ref; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 13681b03c10e..20115770e75a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -1222,7 +1222,8 @@ void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state) static bool iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) { struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); - bool calibrating = READ_ONCE(mvm->calibrating); + bool rfkill_safe_init_done = READ_ONCE(mvm->rfkill_safe_init_done); + bool unified = iwl_mvm_has_unified_ucode(mvm); if (state) set_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status); @@ -1231,15 +1232,23 @@ static bool iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) iwl_mvm_set_rfkill_state(mvm); - /* iwl_run_init_mvm_ucode is waiting for results, abort it */ - if (calibrating) + /* iwl_run_init_mvm_ucode is waiting for results, abort it. */ + if (rfkill_safe_init_done) iwl_abort_notification_waits(&mvm->notif_wait); + /* + * Don't ask the transport to stop the firmware. We'll do it + * after cfg80211 takes us down. + */ + if (unified) + return false; + /* * Stop the device if we run OPERATIONAL firmware or if we are in the * middle of the calibrations. */ - return state && (mvm->fwrt.cur_fw_img != IWL_UCODE_INIT || calibrating); + return state && (mvm->fwrt.cur_fw_img != IWL_UCODE_INIT || + rfkill_safe_init_done); } static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index 59213164f35e..2afce5c41322 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -948,7 +948,7 @@ static inline void iwl_enable_rfkill_int(struct iwl_trans *trans) MSIX_HW_INT_CAUSES_REG_RF_KILL); } - if (trans->cfg->device_family == IWL_DEVICE_FAMILY_9000) { + if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_9000) { /* * On 9000-series devices this bit isn't enabled by default, so * when we power down the device we need set the bit to allow it -- 2.20.1
next prev parent reply index Thread overview: 52+ messages / expand[flat|nested] mbox.gz Atom feed top [not found] <20190627003021.19867-1-sashal@kernel.org> 2019-06-27 0:28 ` [PATCH AUTOSEL 5.1 08/95] bpf: fix out-of-bounds read in __bpf_skc_lookup Sasha Levin 2019-06-27 0:28 ` [PATCH AUTOSEL 5.1 09/95] samples, bpf: fix to change the buffer size for read() Sasha Levin 2019-06-27 0:28 ` [PATCH AUTOSEL 5.1 10/95] samples, bpf: suppress compiler warning Sasha Levin 2019-06-27 0:28 ` [PATCH AUTOSEL 5.1 11/95] bpf, riscv: clear target register high 32-bits for and/or/xor on ALU32 Sasha Levin 2019-06-27 0:28 ` [PATCH AUTOSEL 5.1 12/95] bpf: sockmap, restore sk_write_space when psock gets dropped Sasha Levin 2019-06-27 0:28 ` [PATCH AUTOSEL 5.1 13/95] mac80211: fix rate reporting inside cfg80211_calculate_bitrate_he() Sasha Levin 2019-06-27 0:28 ` [PATCH AUTOSEL 5.1 14/95] bpf: sockmap, fix use after free from sleep in psock backlog workqueue Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 19/95] mac80211: mesh: fix RCU warning Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 20/95] mac80211: free peer keys before vif down in mesh Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 22/95] mwifiex: Fix possible buffer overflows at parsing bss descriptor Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 23/95] mwifiex: Abort at too short BSS descriptor element Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 24/95] bpf, riscv: clear high 32 bits for ALU32 add/sub/neg/lsh/rsh/arsh Sasha Levin 2019-06-27 0:29 ` Sasha Levin [this message] 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 26/95] iwlwifi: clear persistence bit according to device family Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 27/95] iwlwifi: fix AX201 killer sku loading firmware issue Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 28/95] iwlwifi: Fix double-free problems in iwl_req_fw_callback() Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 29/95] mwifiex: Fix heap overflow in mwifiex_uap_parse_tail_ies() Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 30/95] bpf: udp: ipv6: Avoid running reuseport's bpf_prog from __udp6_lib_err Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 31/95] bpf: udp: Avoid calling reuseport's bpf_prog from udp_gro Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 32/95] netfilter: ipv6: nf_defrag: fix leakage of unqueued fragments Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 33/95] tools: bpftool: Fix JSON output when lookup fails Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 36/95] netfilter: ipv6: nf_defrag: accept duplicate fragments again Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 37/95] dt-bindings: can: mcp251x: add mcp25625 support Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 38/95] can: mcp251x: add support for mcp25625 Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 39/95] can: m_can: implement errata "Needless activation of MRAF irq" Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 40/95] can: af_can: Fix error path of can_init() Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 41/95] can: flexcan: Remove unneeded registration message Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 42/95] net: phy: rename Asix Electronics PHY driver Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 43/95] ibmvnic: Do not close unopened driver during reset Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 44/95] ibmvnic: Refresh device multicast list after reset Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 45/95] ibmvnic: Fix unchecked return codes of memory allocations Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 48/95] bpf: lpm_trie: check left child of last leftmost node for NULL Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 54/95] xdp: check device pointer before clearing Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 56/95] mlxsw: spectrum: Disallow prio-tagged packets when PVID is removed Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 58/95] bpf: fix div64 overflow tests to properly detect errors Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 64/95] mac80211: only warn once on chanctx_conf being NULL Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 65/95] mac80211: do not start any work during reconfigure flow Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 66/95] cfg80211: util: fix bit count off by one Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 67/95] cfg80211: report measurement start TSF correctly Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 68/95] bpf, devmap: Fix premature entry free on destroying map Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 69/95] bpf, devmap: Add missing bulk queue free Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 70/95] bpf, devmap: Add missing RCU read lock on flush Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 71/95] bpf, x64: fix stack layout of JITed bpf code Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 72/95] qmi_wwan: add support for QMAP padding in the RX path Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 73/95] qmi_wwan: avoid RCU stalls on device disconnect when in QMAP mode Sasha Levin 2019-06-27 0:29 ` [PATCH AUTOSEL 5.1 74/95] qmi_wwan: extend permitted QMAP mux_id value range Sasha Levin 2019-06-27 0:30 ` [PATCH AUTOSEL 5.1 75/95] bpf: fix nested bpf tracepoints with per-cpu data Sasha Levin 2019-06-27 0:30 ` [PATCH AUTOSEL 5.1 84/95] bnx2x: Check if transceiver implements DDM before access Sasha Levin 2019-06-27 0:30 ` [PATCH AUTOSEL 5.1 86/95] ip6_tunnel: allow not to count pkts on tstats by passing dev as NULL Sasha Levin 2019-06-27 0:30 ` [PATCH AUTOSEL 5.1 87/95] net: lio_core: fix potential sign-extension overflow on large shift Sasha Levin 2019-06-27 0:30 ` [PATCH AUTOSEL 5.1 92/95] net: dsa: mv88e6xxx: fix shift of FID bits in mv88e6185_g1_vtu_loadpurge() Sasha Levin 2019-06-27 0:30 ` [PATCH AUTOSEL 5.1 95/95] net :sunrpc :clnt :Fix xps refcount imbalance on the error path Sasha Levin
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20190627003021.19867-25-sashal@kernel.org \ --to=sashal@kernel.org \ --cc=emmanuel.grumbach@intel.com \ --cc=kvalo@codeaurora.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-wireless@vger.kernel.org \ --cc=luciano.coelho@intel.com \ --cc=netdev@vger.kernel.org \ --cc=stable@vger.kernel.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Netdev Archive on lore.kernel.org Archives are clonable: git clone --mirror https://lore.kernel.org/netdev/0 netdev/git/0.git git clone --mirror https://lore.kernel.org/netdev/1 netdev/git/1.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 netdev netdev/ https://lore.kernel.org/netdev \ netdev@vger.kernel.org public-inbox-index netdev Example config snippet for mirrors Newsgroup available over NNTP: nntp://nntp.lore.kernel.org/org.kernel.vger.netdev AGPL code for this site: git clone https://public-inbox.org/public-inbox.git