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: Mordechay Goodstein <mordechay.goodstein@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Link: https://lore.kernel.org/r/iwlwifi.20210117130510.271f59887fd1.I8ff41236f4e11a25df83d76c982a2a30ba2b9903@changeid Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
This commit is contained in:
parent
25edc8f259
commit
3161a34d65
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
*****************************************************/
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 @@ out_free_trans:
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1320,7 +1320,7 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,
|
|||
iwl_get_cmd_string(trans, cmd->id));
|
||||
ret = -ETIMEDOUT;
|
||||
|
||||
iwl_trans_pcie_sync_nmi(trans);
|
||||
iwl_trans_sync_nmi(trans);
|
||||
goto cancel;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue