diff options
author | Carl Huang <cjhuang@codeaurora.org> | 2020-11-25 19:06:10 +0200 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2020-11-26 11:13:55 +0200 |
commit | 6f481de563dd108bd3df616c80e60f308b7a48e3 (patch) | |
tree | a6224209d9b6b66e74292fcba8a66399c55c16aa | |
parent | 8bd374e3305359ca0be9fe88e8a1edc1abd537eb (diff) |
ath11k: purge rx pktlog when entering suspendath11k-qca6390-bringup-202011260921
This change is to purge rx pktlog when entering suspend and reap
the mon_status buffer to keep it empty. When leaving suspend, host
restarts the reap timer.
Host also stops CE timer and shadow timer before suspend.
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
Signed-off-by: Carl Huang <cjhuang@codeaurora.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-rw-r--r-- | drivers/net/wireless/ath/ath11k/ce.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/ce.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/core.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/dp.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/dp.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/dp_rx.c | 23 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/dp_rx.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/mac.c | 30 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/mac.h | 2 |
9 files changed, 69 insertions, 5 deletions
diff --git a/drivers/net/wireless/ath/ath11k/ce.c b/drivers/net/wireless/ath/ath11k/ce.c index 46c717a344c3..38a710174c87 100644 --- a/drivers/net/wireless/ath/ath11k/ce.c +++ b/drivers/net/wireless/ath/ath11k/ce.c @@ -195,7 +195,7 @@ static bool ath11k_ce_need_shadow_fix(int ce_id) return false; } -static void ath11k_ce_stop_shadow_timers(struct ath11k_base *ab) +void ath11k_ce_stop_shadow_timers(struct ath11k_base *ab) { int i; diff --git a/drivers/net/wireless/ath/ath11k/ce.h b/drivers/net/wireless/ath/ath11k/ce.h index 269b599ac0b0..d6eeef919349 100644 --- a/drivers/net/wireless/ath/ath11k/ce.h +++ b/drivers/net/wireless/ath/ath11k/ce.h @@ -190,4 +190,6 @@ int ath11k_ce_map_service_to_pipe(struct ath11k_base *ab, u16 service_id, int ath11k_ce_attr_attach(struct ath11k_base *ab); void ath11k_ce_get_shadow_config(struct ath11k_base *ab, u32 **shadow_cfg, u32 *shadow_cfg_len); +void ath11k_ce_stop_shadow_timers(struct ath11k_base *ab); + #endif diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 69ff930cd3e1..af1d1b1e097c 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -952,6 +952,9 @@ int ath11k_core_suspend(struct ath11k_base *ab) int ret = 0; if (ab->hw_params.support_suspend) { + ath11k_purge_rx_pktlog(ar, true); + ath11k_ce_stop_shadow_timers(ab); + ath11k_dp_stop_shadow_timers(ab); reinit_completion(&ar->target_suspend); ath11k_wmi_pdev_suspend(ar, 1, 0); ret = wait_for_completion_timeout(&ar->target_suspend, 3 * HZ); @@ -963,7 +966,7 @@ int ath11k_core_suspend(struct ath11k_base *ab) ath11k_warn(ab, "suspend failed\n"); return -EAGAIN; } - + ath11k_purge_rx_pktlog(ar, false); return ath11k_hif_suspend(ab); } return 0; @@ -972,8 +975,11 @@ EXPORT_SYMBOL(ath11k_core_suspend); int ath11k_core_resume(struct ath11k_base *ab) { + struct ath11k *ar = ab->pdevs[0].ar; + if (ab->hw_params.support_suspend) { ath11k_hif_resume(ab); + ath11k_enable_rx_pktlog(ar); ath11k_wmi_pdev_resume(ab->pdevs[0].ar, 0); } diff --git a/drivers/net/wireless/ath/ath11k/dp.c b/drivers/net/wireless/ath/ath11k/dp.c index b7288dc47199..36ea10fb3945 100644 --- a/drivers/net/wireless/ath/ath11k/dp.c +++ b/drivers/net/wireless/ath/ath11k/dp.c @@ -306,7 +306,7 @@ int ath11k_dp_srng_setup(struct ath11k_base *ab, struct dp_srng *ring, return 0; } -static void ath11k_dp_stop_shadow_timers(struct ath11k_base *ab) +void ath11k_dp_stop_shadow_timers(struct ath11k_base *ab) { int i; diff --git a/drivers/net/wireless/ath/ath11k/dp.h b/drivers/net/wireless/ath/ath11k/dp.h index ee8db812589b..05fd06c20780 100644 --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h @@ -40,6 +40,7 @@ struct dp_rx_tid { #define DP_REO_DESC_FREE_THRESHOLD 64 #define DP_REO_DESC_FREE_TIMEOUT_MS 1000 +#define DP_MON_PURGE_TIMEOUT_MS 100 #define DP_MON_SERVICE_BUDGET 128 struct dp_reo_cache_flush_elem { @@ -1640,5 +1641,5 @@ void ath11k_dp_shadow_stop_timer(struct ath11k_base *ab, void ath11k_dp_shadow_init_timer(struct ath11k_base *ab, struct ath11k_hp_update_timer *update_timer, u32 interval, u32 ring_id); - +void ath11k_dp_stop_shadow_timers(struct ath11k_base *ab); #endif diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c index 37e5a408cd62..2bcaf23fa91a 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -274,6 +274,29 @@ static void ath11k_dp_service_mon_ring(struct timer_list *t) msecs_to_jiffies(ATH11K_MON_TIMER_INTERVAL)); } +int ath11k_dp_purge_mon_ring(struct ath11k_base *ab) +{ + int i, buf_reaped = 0; + unsigned long ts = jiffies; + +again: + for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) { + buf_reaped += ath11k_dp_rx_process_mon_rings(ab, i, + NULL, + DP_MON_SERVICE_BUDGET); + } + + /* nothing more to reap */ + if (buf_reaped < DP_MON_SERVICE_BUDGET) + return 0; + + if (time_after(jiffies, ts + + msecs_to_jiffies(DP_MON_PURGE_TIMEOUT_MS))) + return -ETIMEDOUT; + + goto again; +} + /* Returns number of Rx buffers replenished */ int ath11k_dp_rxbufs_replenish(struct ath11k_base *ab, int mac_id, struct dp_rxdma_ring *rx_ring, diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.h b/drivers/net/wireless/ath/ath11k/dp_rx.h index fbea45f79c9b..7d00331cf3e0 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.h +++ b/drivers/net/wireless/ath/ath11k/dp_rx.h @@ -90,5 +90,5 @@ int ath11k_dp_rx_mon_status_bufs_replenish(struct ath11k_base *ab, int mac_id, int ath11k_dp_rx_pdev_mon_detach(struct ath11k *ar); int ath11k_dp_rx_pdev_mon_attach(struct ath11k *ar); int ath11k_peer_rx_frag_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id); - +int ath11k_dp_purge_mon_ring(struct ath11k_base *ab); #endif /* ATH11K_DP_RX_H */ diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index a16b5d69b236..32de67d7df08 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -4106,6 +4106,10 @@ static int ath11k_mac_config_mon_status_default(struct ath11k *ar, bool enable) &tlv_filter); } + if (enable && !ar->ab->hw_params.rxdma1_enable) + mod_timer(&ar->ab->mon_reap_timer, jiffies + + msecs_to_jiffies(ATH11K_MON_TIMER_INTERVAL)); + return ret; } @@ -6437,3 +6441,29 @@ void ath11k_mac_destroy(struct ath11k_base *ab) pdev->ar = NULL; } } + +int ath11k_purge_rx_pktlog(struct ath11k *ar, bool stop_timer) +{ + int ret; + + /* stop timer */ + if (stop_timer) + del_timer_sync(&ar->ab->mon_reap_timer); + + /* reap all the monitor related rings */ + ret = ath11k_dp_purge_mon_ring(ar->ab); + if (ret) + ath11k_warn(ar->ab, + "failed to purge mon_buf ring %d\n", ret); + + return ret; +} + +int ath11k_enable_rx_pktlog(struct ath11k *ar) +{ + /* start reap timer */ + mod_timer(&ar->ab->mon_reap_timer, jiffies + + msecs_to_jiffies(ATH11K_MON_TIMER_INTERVAL)); + + return 0; +} diff --git a/drivers/net/wireless/ath/ath11k/mac.h b/drivers/net/wireless/ath/ath11k/mac.h index 0607479774a9..36d812457b75 100644 --- a/drivers/net/wireless/ath/ath11k/mac.h +++ b/drivers/net/wireless/ath/ath11k/mac.h @@ -146,4 +146,6 @@ int ath11k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx); u8 ath11k_mac_bw_to_mac80211_bw(u8 bw); enum ath11k_supported_bw ath11k_mac_mac80211_bw_to_ath11k_bw(enum rate_info_bw bw); enum hal_encrypt_type ath11k_dp_tx_get_encrypt_type(u32 cipher); +int ath11k_purge_rx_pktlog(struct ath11k *ar, bool stop_timer); +int ath11k_enable_rx_pktlog(struct ath11k *ar); #endif |