18e99ea8dSJohannes Berg // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
28e99ea8dSJohannes Berg /*
38e99ea8dSJohannes Berg  * Copyright (C) 2017 Intel Deutschland GmbH
48e99ea8dSJohannes Berg  * Copyright (C) 2018-2020 Intel Corporation
58e99ea8dSJohannes Berg  */
6eda50cdeSSara Sharon #include "iwl-trans.h"
70232d2cdSSara Sharon #include "iwl-prph.h"
8eda50cdeSSara Sharon #include "iwl-context-info.h"
92ee82402SGolan Ben Ami #include "iwl-context-info-gen3.h"
10eda50cdeSSara Sharon #include "internal.h"
11ae17404eSShahar S Matityahu #include "fw/dbg.h"
12eda50cdeSSara Sharon 
13eda50cdeSSara Sharon /*
14eda50cdeSSara Sharon  * Start up NIC's basic functionality after it has been reset
15eda50cdeSSara Sharon  * (e.g. after platform boot, or shutdown via iwl_pcie_apm_stop())
16eda50cdeSSara Sharon  * NOTE:  This does not load uCode nor start the embedded processor
17eda50cdeSSara Sharon  */
18b6fe2757SGolan Ben Ami int iwl_pcie_gen2_apm_init(struct iwl_trans *trans)
19eda50cdeSSara Sharon {
20eda50cdeSSara Sharon 	int ret = 0;
21eda50cdeSSara Sharon 
22eda50cdeSSara Sharon 	IWL_DEBUG_INFO(trans, "Init card's basic functions\n");
23eda50cdeSSara Sharon 
24eda50cdeSSara Sharon 	/*
25eda50cdeSSara Sharon 	 * Use "set_bit" below rather than "write", to preserve any hardware
26eda50cdeSSara Sharon 	 * bits already set by default after reset.
27eda50cdeSSara Sharon 	 */
28eda50cdeSSara Sharon 
29eda50cdeSSara Sharon 	/*
30eda50cdeSSara Sharon 	 * Disable L0s without affecting L1;
31eda50cdeSSara Sharon 	 * don't wait for ICH L0s (ICH bug W/A)
32eda50cdeSSara Sharon 	 */
33eda50cdeSSara Sharon 	iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS,
34eda50cdeSSara Sharon 		    CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
35eda50cdeSSara Sharon 
36eda50cdeSSara Sharon 	/* Set FH wait threshold to maximum (HW error during stress W/A) */
37eda50cdeSSara Sharon 	iwl_set_bit(trans, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);
38eda50cdeSSara Sharon 
39eda50cdeSSara Sharon 	/*
40eda50cdeSSara Sharon 	 * Enable HAP INTA (interrupt from management bus) to
41eda50cdeSSara Sharon 	 * wake device's PCI Express link L1a -> L0s
42eda50cdeSSara Sharon 	 */
43eda50cdeSSara Sharon 	iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
44eda50cdeSSara Sharon 		    CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
45eda50cdeSSara Sharon 
46eda50cdeSSara Sharon 	iwl_pcie_apm_config(trans);
47eda50cdeSSara Sharon 
487d34a7d7SLuca Coelho 	ret = iwl_finish_nic_init(trans, trans->trans_cfg);
49c96b5eecSJohannes Berg 	if (ret)
50eda50cdeSSara Sharon 		return ret;
51eda50cdeSSara Sharon 
52eda50cdeSSara Sharon 	set_bit(STATUS_DEVICE_ENABLED, &trans->status);
53eda50cdeSSara Sharon 
54eda50cdeSSara Sharon 	return 0;
55eda50cdeSSara Sharon }
56eda50cdeSSara Sharon 
5777c09bc8SSara Sharon static void iwl_pcie_gen2_apm_stop(struct iwl_trans *trans, bool op_mode_leave)
5877c09bc8SSara Sharon {
5977c09bc8SSara Sharon 	IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n");
6077c09bc8SSara Sharon 
6177c09bc8SSara Sharon 	if (op_mode_leave) {
6277c09bc8SSara Sharon 		if (!test_bit(STATUS_DEVICE_ENABLED, &trans->status))
6377c09bc8SSara Sharon 			iwl_pcie_gen2_apm_init(trans);
6477c09bc8SSara Sharon 
6577c09bc8SSara Sharon 		/* inform ME that we are leaving */
6677c09bc8SSara Sharon 		iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG,
6777c09bc8SSara Sharon 			    CSR_RESET_LINK_PWR_MGMT_DISABLED);
6877c09bc8SSara Sharon 		iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
6977c09bc8SSara Sharon 			    CSR_HW_IF_CONFIG_REG_PREPARE |
7077c09bc8SSara Sharon 			    CSR_HW_IF_CONFIG_REG_ENABLE_PME);
7177c09bc8SSara Sharon 		mdelay(1);
7277c09bc8SSara Sharon 		iwl_clear_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG,
7377c09bc8SSara Sharon 			      CSR_RESET_LINK_PWR_MGMT_DISABLED);
7477c09bc8SSara Sharon 		mdelay(5);
7577c09bc8SSara Sharon 	}
7677c09bc8SSara Sharon 
7777c09bc8SSara Sharon 	clear_bit(STATUS_DEVICE_ENABLED, &trans->status);
7877c09bc8SSara Sharon 
7977c09bc8SSara Sharon 	/* Stop device's DMA activity */
8077c09bc8SSara Sharon 	iwl_pcie_apm_stop_master(trans);
8177c09bc8SSara Sharon 
82870c2a11SGolan Ben Ami 	iwl_trans_sw_reset(trans);
8377c09bc8SSara Sharon 
8477c09bc8SSara Sharon 	/*
8577c09bc8SSara Sharon 	 * Clear "initialization complete" bit to move adapter from
8677c09bc8SSara Sharon 	 * D0A* (powered-up Active) --> D0U* (Uninitialized) state.
8777c09bc8SSara Sharon 	 */
886dece0e9SLuca Coelho 	iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
8977c09bc8SSara Sharon }
9077c09bc8SSara Sharon 
91*906d4eb8SJohannes Berg static void iwl_trans_pcie_fw_reset_handshake(struct iwl_trans *trans)
92*906d4eb8SJohannes Berg {
93*906d4eb8SJohannes Berg 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
94*906d4eb8SJohannes Berg 	int ret;
95*906d4eb8SJohannes Berg 
96*906d4eb8SJohannes Berg 	trans_pcie->fw_reset_done = false;
97*906d4eb8SJohannes Berg 
98*906d4eb8SJohannes Berg 	if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210)
99*906d4eb8SJohannes Berg 		iwl_write_umac_prph(trans, UREG_NIC_SET_NMI_DRIVER,
100*906d4eb8SJohannes Berg 				    UREG_NIC_SET_NMI_DRIVER_RESET_HANDSHAKE);
101*906d4eb8SJohannes Berg 	else
102*906d4eb8SJohannes Berg 		iwl_write_umac_prph(trans, UREG_DOORBELL_TO_ISR6,
103*906d4eb8SJohannes Berg 				    UREG_DOORBELL_TO_ISR6_RESET_HANDSHAKE);
104*906d4eb8SJohannes Berg 
105*906d4eb8SJohannes Berg 	/* wait 200ms */
106*906d4eb8SJohannes Berg 	ret = wait_event_timeout(trans_pcie->fw_reset_waitq,
107*906d4eb8SJohannes Berg 				 trans_pcie->fw_reset_done, HZ / 5);
108*906d4eb8SJohannes Berg 	if (!ret)
109*906d4eb8SJohannes Berg 		IWL_ERR(trans,
110*906d4eb8SJohannes Berg 			"firmware didn't ACK the reset - continue anyway\n");
111*906d4eb8SJohannes Berg }
112*906d4eb8SJohannes Berg 
113bab3cb92SEmmanuel Grumbach void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans)
11477c09bc8SSara Sharon {
11577c09bc8SSara Sharon 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
11677c09bc8SSara Sharon 
11777c09bc8SSara Sharon 	lockdep_assert_held(&trans_pcie->mutex);
11877c09bc8SSara Sharon 
11977c09bc8SSara Sharon 	if (trans_pcie->is_down)
12077c09bc8SSara Sharon 		return;
12177c09bc8SSara Sharon 
122*906d4eb8SJohannes Berg 	if (trans_pcie->fw_reset_handshake &&
123*906d4eb8SJohannes Berg 	    trans->state >= IWL_TRANS_FW_STARTED)
124*906d4eb8SJohannes Berg 		iwl_trans_pcie_fw_reset_handshake(trans);
125*906d4eb8SJohannes Berg 
12677c09bc8SSara Sharon 	trans_pcie->is_down = true;
12777c09bc8SSara Sharon 
12877c09bc8SSara Sharon 	/* tell the device to stop sending interrupts */
12977c09bc8SSara Sharon 	iwl_disable_interrupts(trans);
13077c09bc8SSara Sharon 
13177c09bc8SSara Sharon 	/* device going down, Stop using ICT table */
13277c09bc8SSara Sharon 	iwl_pcie_disable_ict(trans);
13377c09bc8SSara Sharon 
13477c09bc8SSara Sharon 	/*
13577c09bc8SSara Sharon 	 * If a HW restart happens during firmware loading,
13677c09bc8SSara Sharon 	 * then the firmware loading might call this function
13777c09bc8SSara Sharon 	 * and later it might be called again due to the
13877c09bc8SSara Sharon 	 * restart. So don't process again if the device is
13977c09bc8SSara Sharon 	 * already dead.
14077c09bc8SSara Sharon 	 */
14177c09bc8SSara Sharon 	if (test_and_clear_bit(STATUS_DEVICE_ENABLED, &trans->status)) {
14277c09bc8SSara Sharon 		IWL_DEBUG_INFO(trans,
14377c09bc8SSara Sharon 			       "DEVICE_ENABLED bit was set and is now cleared\n");
1440cd1ad2dSMordechay Goodstein 		iwl_txq_gen2_tx_stop(trans);
14577c09bc8SSara Sharon 		iwl_pcie_rx_stop(trans);
14677c09bc8SSara Sharon 	}
14777c09bc8SSara Sharon 
14877c09bc8SSara Sharon 	iwl_pcie_ctxt_info_free_paging(trans);
1493681021fSJohannes Berg 	if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
1502ee82402SGolan Ben Ami 		iwl_pcie_ctxt_info_gen3_free(trans);
1512ee82402SGolan Ben Ami 	else
15277c09bc8SSara Sharon 		iwl_pcie_ctxt_info_free(trans);
15377c09bc8SSara Sharon 
15477c09bc8SSara Sharon 	/* Make sure (redundant) we've released our request to stay awake */
15577c09bc8SSara Sharon 	iwl_clear_bit(trans, CSR_GP_CNTRL,
1566dece0e9SLuca Coelho 		      CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
15777c09bc8SSara Sharon 
15877c09bc8SSara Sharon 	/* Stop the device, and put it in low power state */
15977c09bc8SSara Sharon 	iwl_pcie_gen2_apm_stop(trans, false);
16077c09bc8SSara Sharon 
161870c2a11SGolan Ben Ami 	iwl_trans_sw_reset(trans);
16277c09bc8SSara Sharon 
16377c09bc8SSara Sharon 	/*
16477c09bc8SSara Sharon 	 * Upon stop, the IVAR table gets erased, so msi-x won't
16577c09bc8SSara Sharon 	 * work. This causes a bug in RF-KILL flows, since the interrupt
16677c09bc8SSara Sharon 	 * that enables radio won't fire on the correct irq, and the
16777c09bc8SSara Sharon 	 * driver won't be able to handle the interrupt.
16877c09bc8SSara Sharon 	 * Configure the IVAR table again after reset.
16977c09bc8SSara Sharon 	 */
17077c09bc8SSara Sharon 	iwl_pcie_conf_msix_hw(trans_pcie);
17177c09bc8SSara Sharon 
17277c09bc8SSara Sharon 	/*
17377c09bc8SSara Sharon 	 * Upon stop, the APM issues an interrupt if HW RF kill is set.
17477c09bc8SSara Sharon 	 * This is a bug in certain verions of the hardware.
17577c09bc8SSara Sharon 	 * Certain devices also keep sending HW RF kill interrupt all
17677c09bc8SSara Sharon 	 * the time, unless the interrupt is ACKed even if the interrupt
17777c09bc8SSara Sharon 	 * should be masked. Re-ACK all the interrupts here.
17877c09bc8SSara Sharon 	 */
17977c09bc8SSara Sharon 	iwl_disable_interrupts(trans);
18077c09bc8SSara Sharon 
18177c09bc8SSara Sharon 	/* clear all status bits */
18277c09bc8SSara Sharon 	clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status);
18377c09bc8SSara Sharon 	clear_bit(STATUS_INT_ENABLED, &trans->status);
18477c09bc8SSara Sharon 	clear_bit(STATUS_TPOWER_PMI, &trans->status);
18577c09bc8SSara Sharon 
18677c09bc8SSara Sharon 	/*
18777c09bc8SSara Sharon 	 * Even if we stop the HW, we still want the RF kill
18877c09bc8SSara Sharon 	 * interrupt
18977c09bc8SSara Sharon 	 */
19077c09bc8SSara Sharon 	iwl_enable_rfkill_int(trans);
19177c09bc8SSara Sharon 
19277c09bc8SSara Sharon 	/* re-take ownership to prevent other users from stealing the device */
19377c09bc8SSara Sharon 	iwl_pcie_prepare_card_hw(trans);
19477c09bc8SSara Sharon }
19577c09bc8SSara Sharon 
196bab3cb92SEmmanuel Grumbach void iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans)
19777c09bc8SSara Sharon {
19877c09bc8SSara Sharon 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
199326477e4SJohannes Berg 	bool was_in_rfkill;
20077c09bc8SSara Sharon 
20177c09bc8SSara Sharon 	mutex_lock(&trans_pcie->mutex);
202326477e4SJohannes Berg 	trans_pcie->opmode_down = true;
203326477e4SJohannes Berg 	was_in_rfkill = test_bit(STATUS_RFKILL_OPMODE, &trans->status);
204bab3cb92SEmmanuel Grumbach 	_iwl_trans_pcie_gen2_stop_device(trans);
205326477e4SJohannes Berg 	iwl_trans_pcie_handle_stop_rfkill(trans, was_in_rfkill);
20677c09bc8SSara Sharon 	mutex_unlock(&trans_pcie->mutex);
20777c09bc8SSara Sharon }
20877c09bc8SSara Sharon 
209eda50cdeSSara Sharon static int iwl_pcie_gen2_nic_init(struct iwl_trans *trans)
210eda50cdeSSara Sharon {
211eda50cdeSSara Sharon 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
212718a8b23SShaul Triebitz 	int queue_size = max_t(u32, IWL_CMD_QUEUE_SIZE,
213718a8b23SShaul Triebitz 			       trans->cfg->min_txq_size);
214eda50cdeSSara Sharon 
215eda50cdeSSara Sharon 	/* TODO: most of the logic can be removed in A0 - but not in Z0 */
216eda50cdeSSara Sharon 	spin_lock(&trans_pcie->irq_lock);
217eda50cdeSSara Sharon 	iwl_pcie_gen2_apm_init(trans);
218eda50cdeSSara Sharon 	spin_unlock(&trans_pcie->irq_lock);
219eda50cdeSSara Sharon 
220eda50cdeSSara Sharon 	iwl_op_mode_nic_config(trans->op_mode);
221eda50cdeSSara Sharon 
222eda50cdeSSara Sharon 	/* Allocate the RX queue, or reset if it is already allocated */
223eda50cdeSSara Sharon 	if (iwl_pcie_gen2_rx_init(trans))
224eda50cdeSSara Sharon 		return -ENOMEM;
225eda50cdeSSara Sharon 
226eda50cdeSSara Sharon 	/* Allocate or reset and init all Tx and Command queues */
2270cd1ad2dSMordechay Goodstein 	if (iwl_txq_gen2_init(trans, trans->txqs.cmd.q_id, queue_size))
228eda50cdeSSara Sharon 		return -ENOMEM;
229eda50cdeSSara Sharon 
230eda50cdeSSara Sharon 	/* enable shadow regs in HW */
231eda50cdeSSara Sharon 	iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL, 0x800FFFFF);
232eda50cdeSSara Sharon 	IWL_DEBUG_INFO(trans, "Enabling shadow registers in device\n");
233eda50cdeSSara Sharon 
234eda50cdeSSara Sharon 	return 0;
235eda50cdeSSara Sharon }
236eda50cdeSSara Sharon 
237eda50cdeSSara Sharon void iwl_trans_pcie_gen2_fw_alive(struct iwl_trans *trans, u32 scd_addr)
238eda50cdeSSara Sharon {
239eda50cdeSSara Sharon 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
240eda50cdeSSara Sharon 
241eda50cdeSSara Sharon 	iwl_pcie_reset_ict(trans);
242eda50cdeSSara Sharon 
243eda50cdeSSara Sharon 	/* make sure all queue are not stopped/used */
2444f4822b7SMordechay Goodstein 	memset(trans->txqs.queue_stopped, 0,
2454f4822b7SMordechay Goodstein 	       sizeof(trans->txqs.queue_stopped));
2464f4822b7SMordechay Goodstein 	memset(trans->txqs.queue_used, 0, sizeof(trans->txqs.queue_used));
247eda50cdeSSara Sharon 
248eda50cdeSSara Sharon 	/* now that we got alive we can free the fw image & the context info.
249eda50cdeSSara Sharon 	 * paging memory cannot be freed included since FW will still use it
250eda50cdeSSara Sharon 	 */
251eda50cdeSSara Sharon 	iwl_pcie_ctxt_info_free(trans);
252ed3e4c6dSEmmanuel Grumbach 
253ed3e4c6dSEmmanuel Grumbach 	/*
254ed3e4c6dSEmmanuel Grumbach 	 * Re-enable all the interrupts, including the RF-Kill one, now that
255ed3e4c6dSEmmanuel Grumbach 	 * the firmware is alive.
256ed3e4c6dSEmmanuel Grumbach 	 */
257ed3e4c6dSEmmanuel Grumbach 	iwl_enable_interrupts(trans);
258ed3e4c6dSEmmanuel Grumbach 	mutex_lock(&trans_pcie->mutex);
259ed3e4c6dSEmmanuel Grumbach 	iwl_pcie_check_hw_rf_kill(trans);
260ed3e4c6dSEmmanuel Grumbach 	mutex_unlock(&trans_pcie->mutex);
261eda50cdeSSara Sharon }
262eda50cdeSSara Sharon 
263eda50cdeSSara Sharon int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans,
264eda50cdeSSara Sharon 				 const struct fw_img *fw, bool run_in_rfkill)
265eda50cdeSSara Sharon {
266eda50cdeSSara Sharon 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
267eda50cdeSSara Sharon 	bool hw_rfkill;
268eda50cdeSSara Sharon 	int ret;
269eda50cdeSSara Sharon 
270eda50cdeSSara Sharon 	/* This may fail if AMT took ownership of the device */
271eda50cdeSSara Sharon 	if (iwl_pcie_prepare_card_hw(trans)) {
272eda50cdeSSara Sharon 		IWL_WARN(trans, "Exit HW not ready\n");
273eda50cdeSSara Sharon 		ret = -EIO;
274eda50cdeSSara Sharon 		goto out;
275eda50cdeSSara Sharon 	}
276eda50cdeSSara Sharon 
277eda50cdeSSara Sharon 	iwl_enable_rfkill_int(trans);
278eda50cdeSSara Sharon 
279eda50cdeSSara Sharon 	iwl_write32(trans, CSR_INT, 0xFFFFFFFF);
280eda50cdeSSara Sharon 
281eda50cdeSSara Sharon 	/*
282eda50cdeSSara Sharon 	 * We enabled the RF-Kill interrupt and the handler may very
283eda50cdeSSara Sharon 	 * well be running. Disable the interrupts to make sure no other
284eda50cdeSSara Sharon 	 * interrupt can be fired.
285eda50cdeSSara Sharon 	 */
286eda50cdeSSara Sharon 	iwl_disable_interrupts(trans);
287eda50cdeSSara Sharon 
288eda50cdeSSara Sharon 	/* Make sure it finished running */
289eda50cdeSSara Sharon 	iwl_pcie_synchronize_irqs(trans);
290eda50cdeSSara Sharon 
291eda50cdeSSara Sharon 	mutex_lock(&trans_pcie->mutex);
292eda50cdeSSara Sharon 
293eda50cdeSSara Sharon 	/* If platform's RF_KILL switch is NOT set to KILL */
2949ad8fd0bSJohannes Berg 	hw_rfkill = iwl_pcie_check_hw_rf_kill(trans);
295eda50cdeSSara Sharon 	if (hw_rfkill && !run_in_rfkill) {
296eda50cdeSSara Sharon 		ret = -ERFKILL;
297eda50cdeSSara Sharon 		goto out;
298eda50cdeSSara Sharon 	}
299eda50cdeSSara Sharon 
300eda50cdeSSara Sharon 	/* Someone called stop_device, don't try to start_fw */
301eda50cdeSSara Sharon 	if (trans_pcie->is_down) {
302eda50cdeSSara Sharon 		IWL_WARN(trans,
303eda50cdeSSara Sharon 			 "Can't start_fw since the HW hasn't been started\n");
304eda50cdeSSara Sharon 		ret = -EIO;
305eda50cdeSSara Sharon 		goto out;
306eda50cdeSSara Sharon 	}
307eda50cdeSSara Sharon 
308eda50cdeSSara Sharon 	/* make sure rfkill handshake bits are cleared */
309eda50cdeSSara Sharon 	iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
310eda50cdeSSara Sharon 	iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR,
311eda50cdeSSara Sharon 		    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
312eda50cdeSSara Sharon 
313eda50cdeSSara Sharon 	/* clear (again), then enable host interrupts */
314eda50cdeSSara Sharon 	iwl_write32(trans, CSR_INT, 0xFFFFFFFF);
315eda50cdeSSara Sharon 
316eda50cdeSSara Sharon 	ret = iwl_pcie_gen2_nic_init(trans);
317eda50cdeSSara Sharon 	if (ret) {
318eda50cdeSSara Sharon 		IWL_ERR(trans, "Unable to init nic\n");
319eda50cdeSSara Sharon 		goto out;
320eda50cdeSSara Sharon 	}
321eda50cdeSSara Sharon 
3223681021fSJohannes Berg 	if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
3232ee82402SGolan Ben Ami 		ret = iwl_pcie_ctxt_info_gen3_init(trans, fw);
3242ee82402SGolan Ben Ami 	else
32597b00d87SJohannes Berg 		ret = iwl_pcie_ctxt_info_init(trans, fw);
32697b00d87SJohannes Berg 	if (ret)
32797b00d87SJohannes Berg 		goto out;
328eda50cdeSSara Sharon 
329eda50cdeSSara Sharon 	/* re-check RF-Kill state since we may have missed the interrupt */
3309ad8fd0bSJohannes Berg 	hw_rfkill = iwl_pcie_check_hw_rf_kill(trans);
331eda50cdeSSara Sharon 	if (hw_rfkill && !run_in_rfkill)
332eda50cdeSSara Sharon 		ret = -ERFKILL;
333eda50cdeSSara Sharon 
334eda50cdeSSara Sharon out:
335eda50cdeSSara Sharon 	mutex_unlock(&trans_pcie->mutex);
336eda50cdeSSara Sharon 	return ret;
337eda50cdeSSara Sharon }
338