Commit 3161a34d authored by Mordechay Goodstein's avatar Mordechay Goodstein Committed by Luca Coelho
Browse files

iwl-trans: iwlwifi: move sync NMI logic to trans



The code is not directly related to PCIe transport, and it will help
moving sync/async commands logic out of PCIe in the next patches.

Signed-off-by: default avatarMordechay Goodstein <mordechay.goodstein@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20210117130510.271f59887fd1.I8ff41236f4e11a25df83d76c982a2a30ba2b9903@changeid


Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent 25edc8f2
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -445,3 +445,39 @@ int iwl_finish_nic_init(struct iwl_trans *trans,
	return err < 0 ? err : 0;
}
IWL_EXPORT_SYMBOL(iwl_finish_nic_init);

void iwl_trans_sync_nmi_with_addr(struct iwl_trans *trans, u32 inta_addr,
				  u32 sw_err_bit)
{
	unsigned long timeout = jiffies + IWL_TRANS_NMI_TIMEOUT;
	bool interrupts_enabled = test_bit(STATUS_INT_ENABLED, &trans->status);

	/* if the interrupts were already disabled, there is no point in
	 * calling iwl_disable_interrupts
	 */
	if (interrupts_enabled)
		iwl_trans_interrupts(trans, false);

	iwl_force_nmi(trans);
	while (time_after(timeout, jiffies)) {
		u32 inta_hw = iwl_read32(trans, inta_addr);

		/* Error detected by uCode */
		if (inta_hw & sw_err_bit) {
			/* Clear causes register */
			iwl_write32(trans, inta_addr, inta_hw & sw_err_bit);
			break;
		}

		mdelay(1);
	}

	/* enable interrupts only if there were already enabled before this
	 * function to avoid a case were the driver enable interrupts before
	 * proper configurations were made
	 */
	if (interrupts_enabled)
		iwl_trans_interrupts(trans, true);

	iwl_trans_fw_error(trans);
}
+11 −0
Original line number Diff line number Diff line
@@ -514,6 +514,7 @@ struct iwl_trans_rxq_dma_data {
 *	of the trans debugfs
 * @set_pnvm: set the pnvm data in the prph scratch buffer, inside the
 *	context info.
 * @interrupts: disable/enable interrupts to transport
 */
struct iwl_trans_ops {

@@ -587,6 +588,7 @@ struct iwl_trans_ops {
	void (*debugfs_cleanup)(struct iwl_trans *trans);
	void (*sync_nmi)(struct iwl_trans *trans);
	int (*set_pnvm)(struct iwl_trans *trans, const void *data, u32 len);
	void (*interrupts)(struct iwl_trans *trans, bool enable);
};

/**
@@ -1409,6 +1411,9 @@ static inline void iwl_trans_sync_nmi(struct iwl_trans *trans)
		trans->ops->sync_nmi(trans);
}

void iwl_trans_sync_nmi_with_addr(struct iwl_trans *trans, u32 inta_addr,
				  u32 sw_err_bit);

static inline int iwl_trans_set_pnvm(struct iwl_trans *trans,
				     const void *data, u32 len)
{
@@ -1430,6 +1435,12 @@ static inline bool iwl_trans_dbg_ini_valid(struct iwl_trans *trans)
		trans->dbg.external_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED;
}

static inline void iwl_trans_interrupts(struct iwl_trans *trans, bool enable)
{
	if (trans->ops->interrupts)
		trans->ops->interrupts(trans, enable);
}

/*****************************************************
 * transport helper functions
 *****************************************************/
+0 −1
Original line number Diff line number Diff line
@@ -760,7 +760,6 @@ static inline bool iwl_pcie_dbg_on(struct iwl_trans *trans)

void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state);
void iwl_trans_pcie_dump_regs(struct iwl_trans *trans);
void iwl_trans_pcie_sync_nmi(struct iwl_trans *trans);

#ifdef CONFIG_IWLWIFI_DEBUGFS
void iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans);
+26 −46
Original line number Diff line number Diff line
@@ -3284,6 +3284,30 @@ static struct iwl_trans_dump_data
	return dump_data;
}

static void iwl_trans_pci_interrupts(struct iwl_trans *trans, bool enable)
{
	if (enable)
		iwl_enable_interrupts(trans);
	else
		iwl_disable_interrupts(trans);
}

static void iwl_trans_pcie_sync_nmi(struct iwl_trans *trans)
{
	u32 inta_addr, sw_err_bit;
	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);

	if (trans_pcie->msix_enabled) {
		inta_addr = CSR_MSIX_HW_INT_CAUSES_AD;
		sw_err_bit = MSIX_HW_INT_CAUSES_REG_SW_ERR;
	} else {
		inta_addr = CSR_INT;
		sw_err_bit = CSR_INT_BIT_SW_ERR;
	}

	iwl_trans_sync_nmi_with_addr(trans, inta_addr, sw_err_bit);
}

#ifdef CONFIG_PM_SLEEP
static int iwl_trans_pcie_suspend(struct iwl_trans *trans)
{
@@ -3314,7 +3338,8 @@ static void iwl_trans_pcie_resume(struct iwl_trans *trans)
	.dump_data = iwl_trans_pcie_dump_data,				\
	.d3_suspend = iwl_trans_pcie_d3_suspend,			\
	.d3_resume = iwl_trans_pcie_d3_resume,				\
	.sync_nmi = iwl_trans_pcie_sync_nmi
	.interrupts = iwl_trans_pci_interrupts,				\
	.sync_nmi = iwl_trans_pcie_sync_nmi				\

#ifdef CONFIG_PM_SLEEP
#define IWL_TRANS_PM_OPS						\
@@ -3536,48 +3561,3 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
	iwl_trans_free(trans);
	return ERR_PTR(ret);
}

void iwl_trans_pcie_sync_nmi(struct iwl_trans *trans)
{
	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
	unsigned long timeout = jiffies + IWL_TRANS_NMI_TIMEOUT;
	bool interrupts_enabled = test_bit(STATUS_INT_ENABLED, &trans->status);
	u32 inta_addr, sw_err_bit;

	if (trans_pcie->msix_enabled) {
		inta_addr = CSR_MSIX_HW_INT_CAUSES_AD;
		sw_err_bit = MSIX_HW_INT_CAUSES_REG_SW_ERR;
	} else {
		inta_addr = CSR_INT;
		sw_err_bit = CSR_INT_BIT_SW_ERR;
	}

	/* if the interrupts were already disabled, there is no point in
	 * calling iwl_disable_interrupts
	 */
	if (interrupts_enabled)
		iwl_disable_interrupts(trans);

	iwl_force_nmi(trans);
	while (time_after(timeout, jiffies)) {
		u32 inta_hw = iwl_read32(trans, inta_addr);

		/* Error detected by uCode */
		if (inta_hw & sw_err_bit) {
			/* Clear causes register */
			iwl_write32(trans, inta_addr, inta_hw & sw_err_bit);
			break;
		}

		mdelay(1);
	}

	/* enable interrupts only if there were already enabled before this
	 * function to avoid a case were the driver enable interrupts before
	 * proper configurations were made
	 */
	if (interrupts_enabled)
		iwl_enable_interrupts(trans);

	iwl_trans_fw_error(trans);
}
+1 −1
Original line number Diff line number Diff line
@@ -303,7 +303,7 @@ static int iwl_pcie_gen2_send_hcmd_sync(struct iwl_trans *trans,
			       cmd_str);
		ret = -ETIMEDOUT;

		iwl_trans_pcie_sync_nmi(trans);
		iwl_trans_sync_nmi(trans);
		goto cancel;
	}

Loading