diff --git a/qdf/inc/qdf_mc_timer.h b/qdf/inc/qdf_mc_timer.h index 5498064b28..d666c62c42 100644 --- a/qdf/inc/qdf_mc_timer.h +++ b/qdf/inc/qdf_mc_timer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -277,6 +277,13 @@ s64 qdf_get_monotonic_boottime_ns(void); */ void qdf_timer_module_init(void); +/** + * qdf_get_time_of_the_day_ms() - get time of the day in millisec + * + * Return: time of the day in ms + */ +qdf_time_t qdf_get_time_of_the_day_ms(void); + /** * qdf_timer_module_deinit() - Deinitializes a QDF timer module. * diff --git a/qdf/linux/src/qdf_mc_timer.c b/qdf/linux/src/qdf_mc_timer.c index 7e436dbaa1..4fd337cb2c 100644 --- a/qdf/linux/src/qdf_mc_timer.c +++ b/qdf/linux/src/qdf_mc_timer.c @@ -788,6 +788,22 @@ s64 qdf_get_monotonic_boottime_ns(void) } EXPORT_SYMBOL(qdf_get_monotonic_boottime_ns); +qdf_time_t qdf_get_time_of_the_day_ms(void) +{ + struct timeval tv; + qdf_time_t local_time; + struct rtc_time tm; + + do_gettimeofday(&tv); + local_time = (qdf_time_t)(tv.tv_sec - (sys_tz.tz_minuteswest * 60)); + rtc_time_to_tm(local_time, &tm); + + return (tm.tm_hour * 60 * 60 * 1000) + + (tm.tm_min * 60 * 1000) + (tm.tm_sec * 1000) + + (tv.tv_usec / 1000); +} +EXPORT_SYMBOL(qdf_get_time_of_the_day_ms); + /** * qdf_timer_module_deinit() - Deinitializes a QDF timer module. * diff --git a/wmi/inc/wmi_unified_api.h b/wmi/inc/wmi_unified_api.h index 4620c94fa1..ebcdd0d9dd 100644 --- a/wmi/inc/wmi_unified_api.h +++ b/wmi/inc/wmi_unified_api.h @@ -162,6 +162,14 @@ void wmi_mgmt_cmd_record(wmi_unified_t wmi_handle, uint32_t cmd, */ void wmi_unified_detach(struct wmi_unified *wmi_handle); +/** + * API to sync time between host and firmware + * + * @param wmi_handle : handle to WMI. + * @return void. + */ +void wmi_send_time_stamp_sync_cmd_tlv(void *wmi_hdl); + void wmi_unified_remove_work(struct wmi_unified *wmi_handle); diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index 7e4397e681..30bf99ac96 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -1544,6 +1544,7 @@ QDF_STATUS (*send_invoke_neighbor_report_cmd)(wmi_unified_t wmi_handle, struct wmi_invoke_neighbor_report_params *params); void (*wmi_pdev_id_conversion_enable)(wmi_unified_t wmi_handle); +void (*send_time_stamp_sync_cmd)(wmi_unified_t wmi_handle); void (*wmi_free_allocated_event)(A_UINT32 cmd_event_id, void **wmi_cmd_struct_ptr); int (*wmi_check_and_pad_event)(void *os_handle, void *param_struc_ptr, diff --git a/wmi/src/wmi_unified_api.c b/wmi/src/wmi_unified_api.c index 03a4a81334..d6d1a62035 100644 --- a/wmi/src/wmi_unified_api.c +++ b/wmi/src/wmi_unified_api.c @@ -2881,6 +2881,13 @@ QDF_STATUS wmi_unified_log_supported_evt_cmd(void *wmi_hdl, return QDF_STATUS_E_FAILURE; } +void wmi_send_time_stamp_sync_cmd_tlv(void *wmi_hdl) +{ + wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl; + if (wmi_handle->ops->send_time_stamp_sync_cmd) + wmi_handle->ops->send_time_stamp_sync_cmd(wmi_handle); + +} /** * wmi_unified_enable_specific_fw_logs_cmd() - Start/Stop logging of diag log id * @wmi_hdl: wmi handle diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index d68f73535c..8a9d31dbd9 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -1854,6 +1854,59 @@ static QDF_STATUS send_packet_log_disable_cmd_tlv(wmi_unified_t wmi_handle, } #endif +#define WMI_FW_TIME_STAMP_LOW_MASK 0xffffffff +/** + * send_time_stamp_sync_cmd_tlv() - Send WMI command to + * sync time between bwtween host and firmware + * @param wmi_handle : handle to WMI. + * + * Return: None + */ +static void send_time_stamp_sync_cmd_tlv(wmi_unified_t wmi_handle) +{ + wmi_buf_t buf; + A_STATUS status = A_OK; + WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp; + int32_t len; + qdf_time_t time_ms; + + len = sizeof(*time_stamp); + buf = wmi_buf_alloc(wmi_handle, len); + + if (!buf) { + WMI_LOGP(FL("wmi_buf_alloc failed")); + return; + } + time_stamp = + (WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *) + (wmi_buf_data(buf)); + WMITLV_SET_HDR(&time_stamp->tlv_header, + WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param)); + + time_ms = qdf_get_time_of_the_day_ms(); + time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS; + time_stamp->time_stamp_low = time_ms & + WMI_FW_TIME_STAMP_LOW_MASK; + /* + * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms + * wont exceed 27 bit + */ + time_stamp->time_stamp_high = 0; + WMI_LOGD(FL("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d"), + time_stamp->mode, time_stamp->time_stamp_low, + time_stamp->time_stamp_high); + + status = wmi_unified_cmd_send(wmi_handle, buf, + len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); + if (status) { + WMI_LOGE("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command"); + wmi_buf_free(buf); + } + +} + #ifdef WLAN_SUPPORT_FILS /** * extract_swfda_vdev_id_tlv() - extract swfda vdev id from event @@ -22071,6 +22124,7 @@ struct wmi_ops tlv_ops = { .send_vdev_set_param_cmd = send_vdev_set_param_cmd_tlv, .send_stats_request_cmd = send_stats_request_cmd_tlv, .send_packet_log_enable_cmd = send_packet_log_enable_cmd_tlv, + .send_time_stamp_sync_cmd = send_time_stamp_sync_cmd_tlv, .send_packet_log_disable_cmd = send_packet_log_disable_cmd_tlv, .send_beacon_send_cmd = send_beacon_send_cmd_tlv, .send_beacon_tmpl_send_cmd = send_beacon_tmpl_send_cmd_tlv,