@@ -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;
@@ -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
@@ -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);
}
@@ -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;
@@ -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
@@ -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,
@@ -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 */
@@ -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;
+}
@@ -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