From f271ef063ffb76092d695fbb0e3712212be9a9d5 Mon Sep 17 00:00:00 2001 From: Yue Ma Date: Fri, 17 Feb 2017 10:45:26 -0800 Subject: [PATCH] qcacmn: Make sure no PCIe link access when runtime PM suspended There should be no PCIe link access from DP fastpath when device has runtime PM suspended. Runtime PM resume needs to be requested before such access happens. Change-Id: I924ea3e3d5b7d823efd3bd10e2be9b36a5998e24 CRs-fixed: 2023358 --- hif/src/ce/ce_service.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/hif/src/ce/ce_service.c b/hif/src/ce/ce_service.c index 971849f29b79..7bce2fd779e9 100644 --- a/hif/src/ce/ce_service.c +++ b/hif/src/ce/ce_service.c @@ -618,11 +618,22 @@ int ce_send_fast(struct CE_handle *copyeng, qdf_nbuf_t msdu, uint64_t dma_addr; uint32_t user_flags; enum hif_ce_event_type type = FAST_TX_SOFTWARE_INDEX_UPDATE; + bool ok_to_send = true; qdf_spin_lock_bh(&ce_state->ce_index_lock); - Q_TARGET_ACCESS_BEGIN(scn); - DATA_CE_UPDATE_SWINDEX(src_ring->sw_index, scn, ctrl_addr); + /* + * Request runtime PM resume if it has already suspended and make + * sure there is no PCIe link access. + */ + if (hif_pm_runtime_get(hif_hdl) != 0) + ok_to_send = false; + + if (ok_to_send) { + Q_TARGET_ACCESS_BEGIN(scn); + DATA_CE_UPDATE_SWINDEX(src_ring->sw_index, scn, ctrl_addr); + } + write_index = src_ring->write_index; sw_index = src_ring->sw_index; @@ -636,7 +647,8 @@ int ce_send_fast(struct CE_handle *copyeng, qdf_nbuf_t msdu, SLOTS_PER_DATAPATH_TX, CE_RING_DELTA(nentries_mask, write_index, sw_index - 1)); OL_ATH_CE_PKT_ERROR_COUNT_INCR(scn, CE_RING_DELTA_FAIL); - Q_TARGET_ACCESS_END(scn); + if (ok_to_send) + Q_TARGET_ACCESS_END(scn); qdf_spin_unlock_bh(&ce_state->ce_index_lock); return 0; } @@ -725,19 +737,20 @@ int ce_send_fast(struct CE_handle *copyeng, qdf_nbuf_t msdu, src_ring->write_index = write_index; - if (hif_pm_runtime_get(hif_hdl) == 0) { + if (ok_to_send) { if (qdf_likely(ce_state->state == CE_RUNNING)) { type = FAST_TX_WRITE_INDEX_UPDATE; war_ce_src_ring_write_idx_set(scn, ctrl_addr, write_index); + Q_TARGET_ACCESS_END(scn); } else ce_state->state = CE_PENDING; hif_pm_runtime_put(hif_hdl); } + hif_record_ce_desc_event(scn, ce_state->id, type, NULL, NULL, write_index); - Q_TARGET_ACCESS_END(scn); qdf_spin_unlock_bh(&ce_state->ce_index_lock); /* sent 1 packet */