--- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -4467,6 +4467,13 @@ static void ath10k_sta_rc_update(struct static u64 ath10k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { + struct ath10k *ar = hw->priv; + struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); + + mutex_lock(&ar->conf_mutex); + ath10k_wmi_get_tsf( ar, arvif->vdev_id, arvif->vif->addr); + mutex_unlock(&ar->conf_mutex); + /* * FIXME: Return 0 for time being. Need to figure out whether FW * has the API to fetch 64-bit local TSF @@ -4475,6 +4482,27 @@ static u64 ath10k_get_tsf(struct ieee802 return 0; } +static void ath10k_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u64 tsf) +{ + struct ath10k *ar = hw->priv; + struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); + + mutex_lock(&ar->conf_mutex); + ath10k_wmi_set_tsf( ar, arvif->vdev_id, arvif->vif->addr, tsf); + mutex_unlock(&ar->conf_mutex); +} + +static void ath10k_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct ath10k *ar = hw->priv; + struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); + + mutex_lock(&ar->conf_mutex); + ath10k_wmi_reset_tsf( ar, arvif->vdev_id, arvif->vif->addr); + mutex_unlock(&ar->conf_mutex); +} + static int ath10k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, @@ -4535,6 +4563,8 @@ static const struct ieee80211_ops ath10k .set_bitrate_mask = ath10k_set_bitrate_mask, .sta_rc_update = ath10k_sta_rc_update, .get_tsf = ath10k_get_tsf, + .reset_tsf = ath10k_reset_tsf, + .set_tsf = ath10k_set_tsf, .ampdu_action = ath10k_ampdu_action, .get_et_sset_count = ath10k_debug_get_et_sset_count, .get_et_stats = ath10k_debug_get_et_stats, --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -1322,9 +1322,17 @@ static void ath10k_wmi_event_echo(struct static int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb) { + int i; + ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi event debug mesg len %d\n", skb->len); + ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi event data :"); + for (i = 4; i < skb->len; i++) { + ath10k_dbg(ar, ATH10K_DBG_WMI, " %x", skb->data[i]); + } + ath10k_dbg(ar, ATH10K_DBG_WMI, "\n"); + trace_ath10k_wmi_dbglog(ar, skb->data, skb->len); return 0; @@ -4417,3 +4425,64 @@ void ath10k_wmi_detach(struct ath10k *ar ar->wmi.num_mem_chunks = 0; } + +int ath10k_wmi_set_tsf(struct ath10k *ar, u32 vdev_id, const u8 *mac, u64 tsf) +{ + struct sk_buff *skb; + struct wmi_rtt_tsf_cmd *cmd; + + skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi SET TSF %Lu\n", tsf); + cmd = (struct wmi_rtt_tsf_cmd *) skb->data; + cmd->vdev_id = __cpu_to_le32(vdev_id); + cmd->cmd = WMI_TSF_FW_SET; + cmd->tsf_u32 = cpu_to_le32(tsf >> 32); + cmd->tsf_l32 = cpu_to_le32(tsf & 0xffffffff); + + ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi SET TSF %u(l) %u(u)\n", + cmd->tsf_l32, cmd->tsf_u32); + + return ath10k_wmi_cmd_send(ar, skb, + ar->wmi.cmd->rtt_tsf_cmdid); +} + +int ath10k_wmi_reset_tsf(struct ath10k *ar, u32 vdev_id, const u8 *mac) +{ + struct sk_buff *skb; + struct wmi_rtt_tsf_cmd *cmd; + + skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi RESET TSF \n"); + cmd = (struct wmi_rtt_tsf_cmd *) skb->data; + cmd->vdev_id = __cpu_to_le32(vdev_id); + cmd->cmd = WMI_TSF_FW_RESET; + cmd->tsf_u32 = 0; + cmd->tsf_l32 = 0; + + return ath10k_wmi_cmd_send(ar, skb, + ar->wmi.cmd->rtt_tsf_cmdid); +} + +int ath10k_wmi_get_tsf(struct ath10k *ar, u32 vdev_id, const u8 *mac) +{ + struct sk_buff *skb; + struct wmi_rtt_measreq_cmd *cmd; + + skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi GET TSF\n"); + cmd = (struct wmi_rtt_measreq_cmd *) skb->data; + cmd->vdev_id = __cpu_to_le32(vdev_id); + cmd->cmd = WMI_RTT_FW_TSF; + + return ath10k_wmi_cmd_send(ar, skb, + ar->wmi.cmd->rtt_measreq_cmdid); +} --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -4547,6 +4547,32 @@ struct wmi_dbglog_cfg_cmd { __le32 config_valid; } __packed; + +enum wmi_rtt_fw_cmd { + WMI_RTT_FW_RTT = 1, + WMI_RTT_FW_TSF = 2, +}; + +struct wmi_rtt_measreq_cmd { + __le32 vdev_id; + __le32 cmd; +// struct wmi_mac_addr macaddr; +} __packed; + +enum wmi_tsf_fw_cmd { + WMI_TSF_FW_RESET = 1, + WMI_TSF_FW_SET = 2, + WMI_TSF_FW_GET = 3, +}; + +struct wmi_rtt_tsf_cmd { + __le32 vdev_id; + __le32 cmd; + __le32 tsf_l32; + __le32 tsf_u32; +} __packed; + + #define ATH10K_RTS_MAX 2347 #define ATH10K_FRAGMT_THRESHOLD_MIN 540 #define ATH10K_FRAGMT_THRESHOLD_MAX 2346 @@ -4653,5 +4679,8 @@ int ath10k_wmi_pull_fw_stats(struct ath1 struct ath10k_fw_stats *stats); int ath10k_wmi_pdev_pktlog_enable(struct ath10k *ar, u32 ev_list); int ath10k_wmi_pdev_pktlog_disable(struct ath10k *ar); +int ath10k_wmi_set_tsf(struct ath10k *ar, u32 vdev_id, const u8 *mac, u64 tsf); +int ath10k_wmi_reset_tsf(struct ath10k *ar, u32 vdev_id, const u8 *mac); +int ath10k_wmi_get_tsf(struct ath10k *ar, u32 vdev_id, const u8 *mac); #endif /* _WMI_H_ */