Commit 20ddca21 authored by Michal Kazior's avatar Michal Kazior Committed by Kalle Valo

ath10k: add wmi command barrier utility

This allows placing command barriers for explicit
serializing and synchronizing state.

Useful for future driver development.
Signed-off-by: default avatarMichal Kazior <michal.kazior@tieto.com>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent 84d4911b
...@@ -142,6 +142,7 @@ struct ath10k_wmi { ...@@ -142,6 +142,7 @@ struct ath10k_wmi {
enum ath10k_htc_ep_id eid; enum ath10k_htc_ep_id eid;
struct completion service_ready; struct completion service_ready;
struct completion unified_ready; struct completion unified_ready;
struct completion barrier;
wait_queue_head_t tx_credits_wq; wait_queue_head_t tx_credits_wq;
DECLARE_BITMAP(svc_map, WMI_SERVICE_MAX); DECLARE_BITMAP(svc_map, WMI_SERVICE_MAX);
struct wmi_cmd_map *cmd; struct wmi_cmd_map *cmd;
......
...@@ -29,6 +29,9 @@ ...@@ -29,6 +29,9 @@
#include "p2p.h" #include "p2p.h"
#include "hw.h" #include "hw.h"
#define ATH10K_WMI_BARRIER_ECHO_ID 0xBA991E9
#define ATH10K_WMI_BARRIER_TIMEOUT_HZ (3 * HZ)
/* MAIN WMI cmd track */ /* MAIN WMI cmd track */
static struct wmi_cmd_map wmi_cmd_map = { static struct wmi_cmd_map wmi_cmd_map = {
.init_cmdid = WMI_INIT_CMDID, .init_cmdid = WMI_INIT_CMDID,
...@@ -2507,6 +2510,9 @@ void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb) ...@@ -2507,6 +2510,9 @@ void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb)
ath10k_dbg(ar, ATH10K_DBG_WMI, ath10k_dbg(ar, ATH10K_DBG_WMI,
"wmi event echo value 0x%08x\n", "wmi event echo value 0x%08x\n",
le32_to_cpu(arg.value)); le32_to_cpu(arg.value));
if (le32_to_cpu(arg.value) == ATH10K_WMI_BARRIER_ECHO_ID)
complete(&ar->wmi.barrier);
} }
int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb) int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb)
...@@ -7715,6 +7721,30 @@ ath10k_wmi_op_gen_echo(struct ath10k *ar, u32 value) ...@@ -7715,6 +7721,30 @@ ath10k_wmi_op_gen_echo(struct ath10k *ar, u32 value)
return skb; return skb;
} }
int
ath10k_wmi_barrier(struct ath10k *ar)
{
int ret;
int time_left;
spin_lock_bh(&ar->data_lock);
reinit_completion(&ar->wmi.barrier);
spin_unlock_bh(&ar->data_lock);
ret = ath10k_wmi_echo(ar, ATH10K_WMI_BARRIER_ECHO_ID);
if (ret) {
ath10k_warn(ar, "failed to submit wmi echo: %d\n", ret);
return ret;
}
time_left = wait_for_completion_timeout(&ar->wmi.barrier,
ATH10K_WMI_BARRIER_TIMEOUT_HZ);
if (!time_left)
return -ETIMEDOUT;
return 0;
}
static const struct wmi_ops wmi_ops = { static const struct wmi_ops wmi_ops = {
.rx = ath10k_wmi_op_rx, .rx = ath10k_wmi_op_rx,
.map_svc = wmi_main_svc_map, .map_svc = wmi_main_svc_map,
...@@ -8112,6 +8142,7 @@ int ath10k_wmi_attach(struct ath10k *ar) ...@@ -8112,6 +8142,7 @@ int ath10k_wmi_attach(struct ath10k *ar)
init_completion(&ar->wmi.service_ready); init_completion(&ar->wmi.service_ready);
init_completion(&ar->wmi.unified_ready); init_completion(&ar->wmi.unified_ready);
init_completion(&ar->wmi.barrier);
INIT_WORK(&ar->svc_rdy_work, ath10k_wmi_event_service_ready_work); INIT_WORK(&ar->svc_rdy_work, ath10k_wmi_event_service_ready_work);
......
...@@ -6628,5 +6628,6 @@ void ath10k_wmi_10_4_op_fw_stats_fill(struct ath10k *ar, ...@@ -6628,5 +6628,6 @@ void ath10k_wmi_10_4_op_fw_stats_fill(struct ath10k *ar,
char *buf); char *buf);
int ath10k_wmi_op_get_vdev_subtype(struct ath10k *ar, int ath10k_wmi_op_get_vdev_subtype(struct ath10k *ar,
enum wmi_vdev_subtype subtype); enum wmi_vdev_subtype subtype);
int ath10k_wmi_barrier(struct ath10k *ar);
#endif /* _WMI_H_ */ #endif /* _WMI_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment