11590Srgrimes// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
21590Srgrimes/*
31590Srgrimes * Copyright (C) 2017 Intel Deutschland GmbH
41590Srgrimes * Copyright (C) 2018-2023 Intel Corporation
51590Srgrimes */
61590Srgrimes#include "iwl-trans.h"
71590Srgrimes#include "iwl-prph.h"
81590Srgrimes#include "iwl-context-info.h"
91590Srgrimes#include "iwl-context-info-gen3.h"
101590Srgrimes#include "internal.h"
111590Srgrimes#include "fw/dbg.h"
121590Srgrimes
131590Srgrimes#define FW_RESET_TIMEOUT (HZ / 5)
141590Srgrimes
151590Srgrimes/*
161590Srgrimes * Start up NIC's basic functionality after it has been reset
171590Srgrimes * (e.g. after platform boot, or shutdown via iwl_pcie_apm_stop())
181590Srgrimes * NOTE:  This does not load uCode nor start the embedded processor
191590Srgrimes */
201590Srgrimesint iwl_pcie_gen2_apm_init(struct iwl_trans *trans)
211590Srgrimes{
221590Srgrimes	int ret = 0;
231590Srgrimes
241590Srgrimes	IWL_DEBUG_INFO(trans, "Init card's basic functions\n");
251590Srgrimes
261590Srgrimes	/*
271590Srgrimes	 * Use "set_bit" below rather than "write", to preserve any hardware
281590Srgrimes	 * bits already set by default after reset.
291590Srgrimes	 */
301590Srgrimes
311590Srgrimes	/*
321590Srgrimes	 * Disable L0s without affecting L1;
331590Srgrimes	 * don't wait for ICH L0s (ICH bug W/A)
341590Srgrimes	 */
351590Srgrimes	iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS,
361590Srgrimes		    CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
371590Srgrimes
381590Srgrimes	/* Set FH wait threshold to maximum (HW error during stress W/A) */
391590Srgrimes	iwl_set_bit(trans, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);
401590Srgrimes
411590Srgrimes	/*
421590Srgrimes	 * Enable HAP INTA (interrupt from management bus) to
431590Srgrimes	 * wake device's PCI Express link L1a -> L0s
441590Srgrimes	 */
451590Srgrimes	iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
461590Srgrimes		    CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
471590Srgrimes
481590Srgrimes	iwl_pcie_apm_config(trans);
491590Srgrimes
501590Srgrimes	ret = iwl_finish_nic_init(trans);
511590Srgrimes	if (ret)
521590Srgrimes		return ret;
531590Srgrimes
541590Srgrimes	set_bit(STATUS_DEVICE_ENABLED, &trans->status);
551590Srgrimes
561590Srgrimes	return 0;
571590Srgrimes}
581590Srgrimes
591590Srgrimesstatic void iwl_pcie_gen2_apm_stop(struct iwl_trans *trans, bool op_mode_leave)
601590Srgrimes{
611590Srgrimes	IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n");
625811Swollman
631590Srgrimes	if (op_mode_leave) {
641590Srgrimes		if (!test_bit(STATUS_DEVICE_ENABLED, &trans->status))
651590Srgrimes			iwl_pcie_gen2_apm_init(trans);
661590Srgrimes
671590Srgrimes		/* inform ME that we are leaving */
681590Srgrimes		iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG,
691590Srgrimes			    CSR_RESET_LINK_PWR_MGMT_DISABLED);
701590Srgrimes		iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
711590Srgrimes			    CSR_HW_IF_CONFIG_REG_PREPARE |
721590Srgrimes			    CSR_HW_IF_CONFIG_REG_ENABLE_PME);
731590Srgrimes		mdelay(1);
741590Srgrimes		iwl_clear_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG,
751590Srgrimes			      CSR_RESET_LINK_PWR_MGMT_DISABLED);
761590Srgrimes		mdelay(5);
771590Srgrimes	}
781590Srgrimes
791590Srgrimes	clear_bit(STATUS_DEVICE_ENABLED, &trans->status);
801590Srgrimes
811590Srgrimes	/* Stop device's DMA activity */
821590Srgrimes	iwl_pcie_apm_stop_master(trans);
831590Srgrimes
841590Srgrimes	iwl_trans_sw_reset(trans, false);
851590Srgrimes
861590Srgrimes	/*
8712316Speter	 * Clear "initialization complete" bit to move adapter from
881590Srgrimes	 * D0A* (powered-up Active) --> D0U* (Uninitialized) state.
891590Srgrimes	 */
901590Srgrimes	if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ)
911590Srgrimes		iwl_clear_bit(trans, CSR_GP_CNTRL,
921590Srgrimes			      CSR_GP_CNTRL_REG_FLAG_MAC_INIT);
931590Srgrimes	else
941590Srgrimes		iwl_clear_bit(trans, CSR_GP_CNTRL,
951590Srgrimes			      CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
961590Srgrimes}
971590Srgrimes
981590Srgrimesstatic void iwl_trans_pcie_fw_reset_handshake(struct iwl_trans *trans)
991590Srgrimes{
1001590Srgrimes	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1011590Srgrimes	int ret;
1021590Srgrimes
1031590Srgrimes	trans_pcie->fw_reset_state = FW_RESET_REQUESTED;
1041590Srgrimes
1051590Srgrimes	if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210)
1061590Srgrimes		iwl_write_umac_prph(trans, UREG_NIC_SET_NMI_DRIVER,
1071590Srgrimes				    UREG_NIC_SET_NMI_DRIVER_RESET_HANDSHAKE);
1081590Srgrimes	else if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210)
1091590Srgrimes		iwl_write_umac_prph(trans, UREG_DOORBELL_TO_ISR6,
1101590Srgrimes				    UREG_DOORBELL_TO_ISR6_RESET_HANDSHAKE);
1111590Srgrimes	else
1121590Srgrimes		iwl_write32(trans, CSR_DOORBELL_VECTOR,
1131590Srgrimes			    UREG_DOORBELL_TO_ISR6_RESET_HANDSHAKE);
1141590Srgrimes
1151590Srgrimes	/* wait 200ms */
1161590Srgrimes	ret = wait_event_timeout(trans_pcie->fw_reset_waitq,
1171590Srgrimes				 trans_pcie->fw_reset_state != FW_RESET_REQUESTED,
1181590Srgrimes				 FW_RESET_TIMEOUT);
1191590Srgrimes	if (!ret || trans_pcie->fw_reset_state == FW_RESET_ERROR) {
1201590Srgrimes		u32 inta_hw = iwl_read32(trans, CSR_MSIX_HW_INT_CAUSES_AD);
1211590Srgrimes
1221590Srgrimes		IWL_ERR(trans,
1231590Srgrimes			"timeout waiting for FW reset ACK (inta_hw=0x%x)\n",
1249215Swollman			inta_hw);
1259215Swollman
1261590Srgrimes		if (!(inta_hw & MSIX_HW_INT_CAUSES_REG_RESET_DONE))
1271590Srgrimes			iwl_trans_fw_error(trans, true);
12811819Sjulian	}
12911819Sjulian
13011819Sjulian	trans_pcie->fw_reset_state = FW_RESET_IDLE;
13111819Sjulian}
13211819Sjulian
13311819Sjulianvoid _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans)
13411819Sjulian{
13511819Sjulian	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1361590Srgrimes
1371590Srgrimes	lockdep_assert_held(&trans_pcie->mutex);
1381590Srgrimes
1391590Srgrimes	if (trans_pcie->is_down)
1401590Srgrimes		return;
1411590Srgrimes
1421590Srgrimes	if (trans->state >= IWL_TRANS_FW_STARTED)
1431590Srgrimes		if (trans_pcie->fw_reset_handshake)
1441590Srgrimes			iwl_trans_pcie_fw_reset_handshake(trans);
1451590Srgrimes
1461590Srgrimes	trans_pcie->is_down = true;
1471590Srgrimes
1481590Srgrimes	/* tell the device to stop sending interrupts */
1491590Srgrimes	iwl_disable_interrupts(trans);
1501590Srgrimes
1511590Srgrimes	/* device going down, Stop using ICT table */
1521590Srgrimes	iwl_pcie_disable_ict(trans);
1531590Srgrimes
1541590Srgrimes	/*
1551590Srgrimes	 * If a HW restart happens during firmware loading,
1561590Srgrimes	 * then the firmware loading might call this function
1571590Srgrimes	 * and later it might be called again due to the
1581590Srgrimes	 * restart. So don't process again if the device is
1591590Srgrimes	 * already dead.
1601590Srgrimes	 */
16111819Sjulian	if (test_and_clear_bit(STATUS_DEVICE_ENABLED, &trans->status)) {
16211819Sjulian		IWL_DEBUG_INFO(trans,
16311819Sjulian			       "DEVICE_ENABLED bit was set and is now cleared\n");
16411819Sjulian		iwl_pcie_synchronize_irqs(trans);
16511819Sjulian		iwl_pcie_rx_napi_sync(trans);
16611819Sjulian		iwl_txq_gen2_tx_free(trans);
16711819Sjulian		iwl_pcie_rx_stop(trans);
16811819Sjulian	}
16911819Sjulian
17011819Sjulian	iwl_pcie_ctxt_info_free_paging(trans);
17111819Sjulian	if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
1721590Srgrimes		iwl_pcie_ctxt_info_gen3_free(trans, false);
1731590Srgrimes	else
1741590Srgrimes		iwl_pcie_ctxt_info_free(trans);
1751590Srgrimes
1761590Srgrimes	/* Stop the device, and put it in low power state */
1771590Srgrimes	iwl_pcie_gen2_apm_stop(trans, false);
1781590Srgrimes
1791590Srgrimes	/* re-take ownership to prevent other users from stealing the device */
1801590Srgrimes	iwl_trans_sw_reset(trans, true);
1811590Srgrimes
1821590Srgrimes	/*
18313940Swollman	 * Upon stop, the IVAR table gets erased, so msi-x won't
1841590Srgrimes	 * work. This causes a bug in RF-KILL flows, since the interrupt
1851590Srgrimes	 * that enables radio won't fire on the correct irq, and the
1861590Srgrimes	 * driver won't be able to handle the interrupt.
1871590Srgrimes	 * Configure the IVAR table again after reset.
1881590Srgrimes	 */
1891590Srgrimes	iwl_pcie_conf_msix_hw(trans_pcie);
1901590Srgrimes
1911590Srgrimes	/*
1921590Srgrimes	 * Upon stop, the APM issues an interrupt if HW RF kill is set.
1931590Srgrimes	 * This is a bug in certain verions of the hardware.
1941590Srgrimes	 * Certain devices also keep sending HW RF kill interrupt all
1951590Srgrimes	 * the time, unless the interrupt is ACKed even if the interrupt
19613940Swollman	 * should be masked. Re-ACK all the interrupts here.
1971590Srgrimes	 */
19813940Swollman	iwl_disable_interrupts(trans);
19913940Swollman
20013940Swollman	/* clear all status bits */
20113940Swollman	clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status);
20213940Swollman	clear_bit(STATUS_INT_ENABLED, &trans->status);
2031590Srgrimes	clear_bit(STATUS_TPOWER_PMI, &trans->status);
2041590Srgrimes
2051590Srgrimes	/*
2061590Srgrimes	 * Even if we stop the HW, we still want the RF kill
2071590Srgrimes	 * interrupt
2081590Srgrimes	 */
2091590Srgrimes	iwl_enable_rfkill_int(trans);
2101590Srgrimes}
2111590Srgrimes
2121590Srgrimesvoid iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans)
2131590Srgrimes{
2141590Srgrimes	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
2151590Srgrimes	bool was_in_rfkill;
2161590Srgrimes
2171590Srgrimes	iwl_op_mode_time_point(trans->op_mode,
2181590Srgrimes			       IWL_FW_INI_TIME_POINT_HOST_DEVICE_DISABLE,
2191590Srgrimes			       NULL);
2201590Srgrimes
2211590Srgrimes	mutex_lock(&trans_pcie->mutex);
2221590Srgrimes	trans_pcie->opmode_down = true;
2231590Srgrimes	was_in_rfkill = test_bit(STATUS_RFKILL_OPMODE, &trans->status);
2245811Swollman	_iwl_trans_pcie_gen2_stop_device(trans);
2251590Srgrimes	iwl_trans_pcie_handle_stop_rfkill(trans, was_in_rfkill);
2261590Srgrimes	mutex_unlock(&trans_pcie->mutex);
2271590Srgrimes}
2281590Srgrimes
2291590Srgrimesstatic int iwl_pcie_gen2_nic_init(struct iwl_trans *trans)
2301590Srgrimes{
2311590Srgrimes	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
2323534Sdg	int queue_size = max_t(u32, IWL_CMD_QUEUE_SIZE,
2331590Srgrimes			       trans->cfg->min_txq_size);
2341590Srgrimes	int ret;
2351590Srgrimes
2361590Srgrimes	/* TODO: most of the logic can be removed in A0 - but not in Z0 */
2371590Srgrimes	spin_lock_bh(&trans_pcie->irq_lock);
2381590Srgrimes	ret = iwl_pcie_gen2_apm_init(trans);
2391590Srgrimes	spin_unlock_bh(&trans_pcie->irq_lock);
2403534Sdg	if (ret)
2413534Sdg		return ret;
2423534Sdg
2431590Srgrimes	iwl_op_mode_nic_config(trans->op_mode);
2441590Srgrimes
2451590Srgrimes	/* Allocate the RX queue, or reset if it is already allocated */
2461590Srgrimes	if (iwl_pcie_gen2_rx_init(trans))
2471590Srgrimes		return -ENOMEM;
2481590Srgrimes
24911819Sjulian	/* Allocate or reset and init all Tx and Command queues */
25011819Sjulian	if (iwl_txq_gen2_init(trans, trans->txqs.cmd.q_id, queue_size))
2511590Srgrimes		return -ENOMEM;
2521590Srgrimes
2531590Srgrimes	/* enable shadow regs in HW */
2541590Srgrimes	iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL, 0x800FFFFF);
25513940Swollman	IWL_DEBUG_INFO(trans, "Enabling shadow registers in device\n");
2561590Srgrimes
2571590Srgrimes	return 0;
25813940Swollman}
2591590Srgrimes
2605811Swollmanstatic void iwl_pcie_get_rf_name(struct iwl_trans *trans)
2611590Srgrimes{
2621590Srgrimes	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
2631590Srgrimes	char *buf = trans_pcie->rf_name;
2641590Srgrimes	size_t buflen = sizeof(trans_pcie->rf_name);
2651590Srgrimes	size_t pos;
2661590Srgrimes	u32 version;
2671590Srgrimes
2681590Srgrimes	if (buf[0])
2691590Srgrimes		return;
2701590Srgrimes
2711590Srgrimes	switch (CSR_HW_RFID_TYPE(trans->hw_rf_id)) {
2721590Srgrimes	case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_JF):
2731590Srgrimes		pos = scnprintf(buf, buflen, "JF");
2741590Srgrimes		break;
2751590Srgrimes	case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_GF):
2761590Srgrimes		pos = scnprintf(buf, buflen, "GF");
2771590Srgrimes		break;
2781590Srgrimes	case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_GF4):
2791590Srgrimes		pos = scnprintf(buf, buflen, "GF4");
2801590Srgrimes		break;
2811590Srgrimes	case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_HR):
2821590Srgrimes		pos = scnprintf(buf, buflen, "HR");
2831590Srgrimes		break;
2841590Srgrimes	case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_HR1):
2851590Srgrimes		pos = scnprintf(buf, buflen, "HR1");
2861590Srgrimes		break;
2871590Srgrimes	case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_HRCDB):
2881590Srgrimes		pos = scnprintf(buf, buflen, "HRCDB");
2891590Srgrimes		break;
2901590Srgrimes	case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_MS):
2911590Srgrimes		pos = scnprintf(buf, buflen, "MS");
2929215Swollman		break;
2935811Swollman	case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_FM):
2945811Swollman		pos = scnprintf(buf, buflen, "FM");
2951590Srgrimes		break;
2961590Srgrimes	case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_WP):
2971590Srgrimes		if (SILICON_Z_STEP ==
2981590Srgrimes		    CSR_HW_RFID_STEP(trans->hw_rf_id))
2991590Srgrimes			pos = scnprintf(buf, buflen, "WHTC");
3001590Srgrimes		else
3011590Srgrimes			pos = scnprintf(buf, buflen, "WH");
3021590Srgrimes		break;
3031590Srgrimes	default:
3041590Srgrimes		return;
3051590Srgrimes	}
3061590Srgrimes
3071590Srgrimes	switch (CSR_HW_RFID_TYPE(trans->hw_rf_id)) {
3081590Srgrimes	case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_HR):
3091590Srgrimes	case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_HR1):
3101590Srgrimes	case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_HRCDB):
3111590Srgrimes		version = iwl_read_prph(trans, CNVI_MBOX_C);
3121590Srgrimes		switch (version) {
3131590Srgrimes		case 0x20000:
3141590Srgrimes			pos += scnprintf(buf + pos, buflen - pos, " B3");
3151590Srgrimes			break;
3161590Srgrimes		case 0x120000:
3171590Srgrimes			pos += scnprintf(buf + pos, buflen - pos, " B5");
3181590Srgrimes			break;
3191590Srgrimes		default:
3201590Srgrimes			pos += scnprintf(buf + pos, buflen - pos,
3211590Srgrimes					 " (0x%x)", version);
3221590Srgrimes			break;
3231590Srgrimes		}
3241590Srgrimes		break;
3251590Srgrimes	default:
3261590Srgrimes		break;
3271590Srgrimes	}
3281590Srgrimes
3291590Srgrimes	pos += scnprintf(buf + pos, buflen - pos, ", rfid=0x%x",
3301590Srgrimes			 trans->hw_rf_id);
3311590Srgrimes
3321590Srgrimes	IWL_INFO(trans, "Detected RF %s\n", buf);
3331590Srgrimes
3341590Srgrimes	/*
3351590Srgrimes	 * also add a \n for debugfs - need to do it after printing
3361590Srgrimes	 * since our IWL_INFO machinery wants to see a static \n at
3371590Srgrimes	 * the end of the string
3381590Srgrimes	 */
3391590Srgrimes	pos += scnprintf(buf + pos, buflen - pos, "\n");
3401590Srgrimes}
3411590Srgrimes
3421590Srgrimesvoid iwl_trans_pcie_gen2_fw_alive(struct iwl_trans *trans, u32 scd_addr)
3431590Srgrimes{
3441590Srgrimes	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
3451590Srgrimes
3465811Swollman	iwl_pcie_reset_ict(trans);
3475811Swollman
3485811Swollman	/* make sure all queue are not stopped/used */
3491590Srgrimes	memset(trans->txqs.queue_stopped, 0,
3505811Swollman	       sizeof(trans->txqs.queue_stopped));
3515811Swollman	memset(trans->txqs.queue_used, 0, sizeof(trans->txqs.queue_used));
3525811Swollman
3531590Srgrimes	/* now that we got alive we can free the fw image & the context info.
3545811Swollman	 * paging memory cannot be freed included since FW will still use it
3551590Srgrimes	 */
3565811Swollman	if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
3575811Swollman		iwl_pcie_ctxt_info_gen3_free(trans, true);
3585811Swollman	else
3595811Swollman		iwl_pcie_ctxt_info_free(trans);
3605811Swollman
3615811Swollman	/*
3625811Swollman	 * Re-enable all the interrupts, including the RF-Kill one, now that
3631590Srgrimes	 * the firmware is alive.
3641590Srgrimes	 */
3651590Srgrimes	iwl_enable_interrupts(trans);
3661590Srgrimes	mutex_lock(&trans_pcie->mutex);
3671590Srgrimes	iwl_pcie_check_hw_rf_kill(trans);
3681590Srgrimes
3691590Srgrimes	iwl_pcie_get_rf_name(trans);
3701590Srgrimes	mutex_unlock(&trans_pcie->mutex);
3711590Srgrimes}
3721590Srgrimes
3731590Srgrimesstatic bool iwl_pcie_set_ltr(struct iwl_trans *trans)
3741590Srgrimes{
37513431Speter	u32 ltr_val = CSR_LTR_LONG_VAL_AD_NO_SNOOP_REQ |
3761590Srgrimes		      u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC,
3771590Srgrimes				      CSR_LTR_LONG_VAL_AD_NO_SNOOP_SCALE) |
3781590Srgrimes		      u32_encode_bits(250,
3791590Srgrimes				      CSR_LTR_LONG_VAL_AD_NO_SNOOP_VAL) |
3801590Srgrimes		      CSR_LTR_LONG_VAL_AD_SNOOP_REQ |
3811590Srgrimes		      u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC,
38213431Speter				      CSR_LTR_LONG_VAL_AD_SNOOP_SCALE) |
38313431Speter		      u32_encode_bits(250, CSR_LTR_LONG_VAL_AD_SNOOP_VAL);
38413431Speter
38513431Speter	/*
38613431Speter	 * To workaround hardware latency issues during the boot process,
38713431Speter	 * initialize the LTR to ~250 usec (see ltr_val above).
38813431Speter	 * The firmware initializes this again later (to a smaller value).
3891590Srgrimes	 */
3901590Srgrimes	if ((trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210 ||
3911590Srgrimes	     trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000) &&
3921590Srgrimes	    !trans->trans_cfg->integrated) {
3931590Srgrimes		iwl_write32(trans, CSR_LTR_LONG_VAL_AD, ltr_val);
3941590Srgrimes		return true;
3951590Srgrimes	}
3961590Srgrimes
3971590Srgrimes	if (trans->trans_cfg->integrated &&
3981590Srgrimes	    trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000) {
3991590Srgrimes		iwl_write_prph(trans, HPM_MAC_LTR_CSR, HPM_MAC_LRT_ENABLE_ALL);
4001590Srgrimes		iwl_write_prph(trans, HPM_UMAC_LTR, ltr_val);
4011590Srgrimes		return true;
4021590Srgrimes	}
4031590Srgrimes
4041590Srgrimes	if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210) {
4051590Srgrimes		/* First clear the interrupt, just in case */
4069215Swollman		iwl_write32(trans, CSR_MSIX_HW_INT_CAUSES_AD,
4071590Srgrimes			    MSIX_HW_INT_CAUSES_REG_IML);
4081590Srgrimes		/* In this case, unfortunately the same ROM bug exists in the
4091590Srgrimes		 * device (not setting LTR correctly), but we don't have control
4101590Srgrimes		 * over the settings from the host due to some hardware security
4111590Srgrimes		 * features. The only workaround we've been able to come up with
4121590Srgrimes		 * so far is to try to keep the CPU and device busy by polling
4131590Srgrimes		 * it and the IML (image loader) completed interrupt.
4141590Srgrimes		 */
4151590Srgrimes		return false;
4161590Srgrimes	}
4171590Srgrimes
4181590Srgrimes	/* nothing needs to be done on other devices */
4191590Srgrimes	return true;
4201590Srgrimes}
4211590Srgrimes
4221590Srgrimesstatic void iwl_pcie_spin_for_iml(struct iwl_trans *trans)
4231590Srgrimes{
42411819Sjulian/* in practice, this seems to complete in around 20-30ms at most, wait 100 */
42511819Sjulian#define IML_WAIT_TIMEOUT	(HZ / 10)
42611819Sjulian	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
4271590Srgrimes	unsigned long end_time = jiffies + IML_WAIT_TIMEOUT;
4281590Srgrimes	u32 value, loops = 0;
4291590Srgrimes	bool irq = false;
43013940Swollman
4311590Srgrimes	if (WARN_ON(!trans_pcie->iml))
4321590Srgrimes		return;
4331590Srgrimes
43413940Swollman	value = iwl_read32(trans, CSR_LTR_LAST_MSG);
4351590Srgrimes	IWL_DEBUG_INFO(trans, "Polling for IML load - CSR_LTR_LAST_MSG=0x%x\n",
4361590Srgrimes		       value);
4371590Srgrimes
4381590Srgrimes	while (time_before(jiffies, end_time)) {
4391590Srgrimes		if (iwl_read32(trans, CSR_MSIX_HW_INT_CAUSES_AD) &
4401590Srgrimes				MSIX_HW_INT_CAUSES_REG_IML) {
4411590Srgrimes			irq = true;
4421590Srgrimes			break;
4431590Srgrimes		}
4441590Srgrimes		/* Keep the CPU and device busy. */
4451590Srgrimes		value = iwl_read32(trans, CSR_LTR_LAST_MSG);
4461590Srgrimes		loops++;
4471590Srgrimes	}
4481590Srgrimes
4491590Srgrimes	IWL_DEBUG_INFO(trans,
4501590Srgrimes		       "Polled for IML load: irq=%d, loops=%d, CSR_LTR_LAST_MSG=0x%x\n",
4511590Srgrimes		       irq, loops, value);
4521590Srgrimes
4531590Srgrimes	/* We don't fail here even if we timed out - maybe we get lucky and the
4541590Srgrimes	 * interrupt comes in later (and we get alive from firmware) and then
4551590Srgrimes	 * we're all happy - but if not we'll fail on alive timeout or get some
4561590Srgrimes	 * other error out.
4571590Srgrimes	 */
4581590Srgrimes}
4591590Srgrimes
4601590Srgrimesint iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans,
4611590Srgrimes				 const struct fw_img *fw, bool run_in_rfkill)
4621590Srgrimes{
4631590Srgrimes	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
4641590Srgrimes	bool hw_rfkill, keep_ram_busy;
4651590Srgrimes	int ret;
4661590Srgrimes
4671590Srgrimes	/* This may fail if AMT took ownership of the device */
4681590Srgrimes	if (iwl_pcie_prepare_card_hw(trans)) {
4691590Srgrimes		IWL_WARN(trans, "Exit HW not ready\n");
4701590Srgrimes		return -EIO;
4711590Srgrimes	}
4721590Srgrimes
4731590Srgrimes	iwl_enable_rfkill_int(trans);
4741590Srgrimes
4759776Sdg	iwl_write32(trans, CSR_INT, 0xFFFFFFFF);
4761590Srgrimes
4771590Srgrimes	/*
4781590Srgrimes	 * We enabled the RF-Kill interrupt and the handler may very
4791590Srgrimes	 * well be running. Disable the interrupts to make sure no other
4801590Srgrimes	 * interrupt can be fired.
4811590Srgrimes	 */
4821590Srgrimes	iwl_disable_interrupts(trans);
4831590Srgrimes
4841590Srgrimes	/* Make sure it finished running */
4851590Srgrimes	iwl_pcie_synchronize_irqs(trans);
4861590Srgrimes
4871590Srgrimes	mutex_lock(&trans_pcie->mutex);
4881590Srgrimes
4891590Srgrimes	/* If platform's RF_KILL switch is NOT set to KILL */
4901590Srgrimes	hw_rfkill = iwl_pcie_check_hw_rf_kill(trans);
4911590Srgrimes	if (hw_rfkill && !run_in_rfkill) {
4921590Srgrimes		ret = -ERFKILL;
4931590Srgrimes		goto out;
4941590Srgrimes	}
4951590Srgrimes
4961590Srgrimes	/* Someone called stop_device, don't try to start_fw */
4971590Srgrimes	if (trans_pcie->is_down) {
4981590Srgrimes		IWL_WARN(trans,
4991590Srgrimes			 "Can't start_fw since the HW hasn't been started\n");
5001590Srgrimes		ret = -EIO;
5011590Srgrimes		goto out;
5021590Srgrimes	}
5031590Srgrimes
5041590Srgrimes	/* make sure rfkill handshake bits are cleared */
5051590Srgrimes	iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
5061590Srgrimes	iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR,
5071590Srgrimes		    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
5081590Srgrimes
5091590Srgrimes	/* clear (again), then enable host interrupts */
5101590Srgrimes	iwl_write32(trans, CSR_INT, 0xFFFFFFFF);
5111590Srgrimes
5121590Srgrimes	ret = iwl_pcie_gen2_nic_init(trans);
5131590Srgrimes	if (ret) {
5141590Srgrimes		IWL_ERR(trans, "Unable to init nic\n");
5151590Srgrimes		goto out;
5161590Srgrimes	}
5171590Srgrimes
5181590Srgrimes	if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
5191590Srgrimes		ret = iwl_pcie_ctxt_info_gen3_init(trans, fw);
5201590Srgrimes	else
5211590Srgrimes		ret = iwl_pcie_ctxt_info_init(trans, fw);
5221590Srgrimes	if (ret)
5231590Srgrimes		goto out;
5241590Srgrimes
5251590Srgrimes	keep_ram_busy = !iwl_pcie_set_ltr(trans);
5261590Srgrimes
5271590Srgrimes	if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {
5281590Srgrimes		iwl_write32(trans, CSR_FUNC_SCRATCH, CSR_FUNC_SCRATCH_INIT_VALUE);
5291590Srgrimes		iwl_set_bit(trans, CSR_GP_CNTRL,
5301590Srgrimes			    CSR_GP_CNTRL_REG_FLAG_ROM_START);
5311590Srgrimes	} else if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
5321590Srgrimes		iwl_write_umac_prph(trans, UREG_CPU_INIT_RUN, 1);
5331590Srgrimes	} else {
5341590Srgrimes		iwl_write_prph(trans, UREG_CPU_INIT_RUN, 1);
5351590Srgrimes	}
5361590Srgrimes
5371590Srgrimes	if (keep_ram_busy)
5381590Srgrimes		iwl_pcie_spin_for_iml(trans);
5391590Srgrimes
5401590Srgrimes	/* re-check RF-Kill state since we may have missed the interrupt */
5411590Srgrimes	hw_rfkill = iwl_pcie_check_hw_rf_kill(trans);
5421590Srgrimes	if (hw_rfkill && !run_in_rfkill)
5431590Srgrimes		ret = -ERFKILL;
5441590Srgrimes
5451590Srgrimesout:
5461590Srgrimes	mutex_unlock(&trans_pcie->mutex);
5471590Srgrimes	return ret;
5483534Sdg}
5491590Srgrimes