diff options
author | Rakesh Pillai <pillair@codeaurora.org> | 2020-08-31 18:28:47 +0300 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2020-09-01 14:59:33 +0300 |
commit | b92aba35d39d10d8a6bdf2495172fd490c598b4a (patch) | |
tree | 11a0e7e612917fab671a87bf3c7678bb08ead3a4 /drivers/net/wireless/ath/ath10k/ce.h | |
parent | e96eecdb290af89e3aca05df835d6123c8947bee (diff) |
ath10k: Add interrupt summary based CE processing
Currently the NAPI processing loops through all
the copy engines and processes a particular copy
engine is the copy completion is set for that copy
engine. The host driver is not supposed to access
any copy engine register after clearing the interrupt
status register.
This might result in kernel crash like the one below
[ 1159.220143] Call trace:
[ 1159.220170] ath10k_snoc_read32+0x20/0x40 [ath10k_snoc]
[ 1159.220193] ath10k_ce_per_engine_service_any+0x78/0x130 [ath10k_core]
[ 1159.220203] ath10k_snoc_napi_poll+0x38/0x8c [ath10k_snoc]
[ 1159.220270] net_rx_action+0x100/0x3b0
[ 1159.220312] __do_softirq+0x164/0x30c
[ 1159.220345] run_ksoftirqd+0x2c/0x64
[ 1159.220380] smpboot_thread_fn+0x1b0/0x288
[ 1159.220405] kthread+0x11c/0x12c
[ 1159.220423] ret_from_fork+0x10/0x18
To avoid such a scenario, we generate an interrupt
summary by reading the copy completion for all the
copy engine before actually processing any of them.
This will avoid reading the interrupt status register
for any CE after the interrupt status is cleared.
Tested-on: WCN3990 hw1.0 SNOC WLAN.HL.3.1-01040-QCAHLSWMTPLZ-1
Signed-off-by: Rakesh Pillai <pillair@codeaurora.org>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Tested-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/1593193967-29897-1-git-send-email-pillair@codeaurora.org
Diffstat (limited to 'drivers/net/wireless/ath/ath10k/ce.h')
-rw-r--r-- | drivers/net/wireless/ath/ath10k/ce.h | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/net/wireless/ath/ath10k/ce.h b/drivers/net/wireless/ath/ath10k/ce.h index 75df79d43120..a440aaf74aa4 100644 --- a/drivers/net/wireless/ath/ath10k/ce.h +++ b/drivers/net/wireless/ath/ath10k/ce.h @@ -259,6 +259,8 @@ int ath10k_ce_disable_interrupts(struct ath10k *ar); void ath10k_ce_enable_interrupts(struct ath10k *ar); void ath10k_ce_dump_registers(struct ath10k *ar, struct ath10k_fw_crash_data *crash_data); + +u32 ath10k_ce_gen_interrupt_summary(struct ath10k *ar); void ath10k_ce_alloc_rri(struct ath10k *ar); void ath10k_ce_free_rri(struct ath10k *ar); @@ -369,7 +371,6 @@ static inline u32 ath10k_ce_base_address(struct ath10k *ar, unsigned int ce_id) (((x) & CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK) >> \ CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB) #define CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS 0x0000 -#define CE_INTERRUPT_SUMMARY (GENMASK(CE_COUNT_MAX - 1, 0)) static inline u32 ath10k_ce_interrupt_summary(struct ath10k *ar) { @@ -380,7 +381,7 @@ static inline u32 ath10k_ce_interrupt_summary(struct ath10k *ar) ce->bus_ops->read32((ar), CE_WRAPPER_BASE_ADDRESS + CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS)); else - return CE_INTERRUPT_SUMMARY; + return ath10k_ce_gen_interrupt_summary(ar); } /* Host software's Copy Engine configuration. */ |