diff options
author | Michal Kazior <michal.kazior@tieto.com> | 2014-05-26 14:02:59 +0400 |
---|---|---|
committer | Kalle Valo <kvalo@qca.qualcomm.com> | 2014-05-27 13:32:10 +0400 |
commit | 08b8aa0931830cc4b96b47f884fe623aef5c4b84 (patch) | |
tree | 89d93b2cabc0642aa6db31bc12083084f82ef0c7 /drivers/net/wireless/ath/ath10k/ce.c | |
parent | 7147a13135ee717397969d33a139204dfe793022 (diff) | |
download | linux-08b8aa0931830cc4b96b47f884fe623aef5c4b84.tar.xz |
ath10k: abort incomplete scatter-gather pci tx properly
This prevents leaving incomplete scatter-gather
transfer on CE rings which can lead firmware to
crash.
Reported-By: Avery Pennarun <apenwarr@gmail.com>
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath10k/ce.c')
-rw-r--r-- | drivers/net/wireless/ath/ath10k/ce.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c index 1e4cad8632b5..d185dc0cd12b 100644 --- a/drivers/net/wireless/ath/ath10k/ce.c +++ b/drivers/net/wireless/ath/ath10k/ce.c @@ -329,6 +329,33 @@ exit: return ret; } +void __ath10k_ce_send_revert(struct ath10k_ce_pipe *pipe) +{ + struct ath10k *ar = pipe->ar; + struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); + struct ath10k_ce_ring *src_ring = pipe->src_ring; + u32 ctrl_addr = pipe->ctrl_addr; + + lockdep_assert_held(&ar_pci->ce_lock); + + /* + * This function must be called only if there is an incomplete + * scatter-gather transfer (before index register is updated) + * that needs to be cleaned up. + */ + if (WARN_ON_ONCE(src_ring->write_index == src_ring->sw_index)) + return; + + if (WARN_ON_ONCE(src_ring->write_index == + ath10k_ce_src_ring_write_index_get(ar, ctrl_addr))) + return; + + src_ring->write_index--; + src_ring->write_index &= src_ring->nentries_mask; + + src_ring->per_transfer_context[src_ring->write_index] = NULL; +} + int ath10k_ce_send(struct ath10k_ce_pipe *ce_state, void *per_transfer_context, u32 buffer, |