mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 19:21:31 -04:00
qcacld-3.0: enhance the robustness of TSF capturing
1. Failed to get TSF if issuing cap_tsf more than 1 time continuously, due to the TSF value will be reset by the following 'cap_tsf' command, however, these 'cap_tsf' won't be excuted actually, because 'get_tsf' was not received after last successful 'cap_tsf'. To fix it, do TSF reset only if 'cap_tsf' will be actually excuted. 2. Add flag 'cap_tsf_flag' to make sure cap_tsf being executed serially. 3. Add flag 'tsf_ready_flag' to indicate whether TSF feature has been initialized successfully. Add 'TSF_NOT_READY' in 'hdd_tsf_get_state' to indicate this state. Propagated from qcacld-2.0 Change-Id: Ib768e3d7f0b33a75e8bd838d4ed1c0b84e3aa13d CRs-Fixed: 2057693
This commit is contained in:
parent
c7f560cb21
commit
f5d5b5f5cc
4 changed files with 293 additions and 138 deletions
|
|
@ -1051,10 +1051,7 @@ struct hdd_adapter_s {
|
|||
|
||||
#ifdef WLAN_FEATURE_TSF
|
||||
/* tsf value received from firmware */
|
||||
uint32_t tsf_low;
|
||||
uint32_t tsf_high;
|
||||
/* TSF capture state */
|
||||
enum hdd_tsf_capture_state tsf_state;
|
||||
uint64_t cur_target_time;
|
||||
uint64_t tsf_sync_soc_timer;
|
||||
#endif
|
||||
|
||||
|
|
@ -1620,6 +1617,14 @@ struct hdd_context_s {
|
|||
/* Lock to control access to dnbs and coex avoid freq list */
|
||||
struct mutex avoid_freq_lock;
|
||||
#endif
|
||||
#ifdef WLAN_FEATURE_TSF
|
||||
/* indicate whether tsf has been initialized */
|
||||
qdf_atomic_t tsf_ready_flag;
|
||||
/* indicate whether it's now capturing tsf(updating tstamp-pair) */
|
||||
qdf_atomic_t cap_tsf_flag;
|
||||
/* the context that is capturing tsf */
|
||||
hdd_adapter_t *cap_tsf_context;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
* @TSF_GET_FAIL: get fail
|
||||
* @TSF_RESET_GPIO_FAIL: GPIO reset fail
|
||||
* @TSF_SAP_NOT_STARTED_NO_TSF SAP not started
|
||||
* @TSF_NOT_READY: TSF module is not initialized or init failed
|
||||
*/
|
||||
enum hdd_tsf_get_state {
|
||||
TSF_RETURN = 0,
|
||||
|
|
@ -47,7 +48,8 @@ enum hdd_tsf_get_state {
|
|||
TSF_CAPTURE_FAIL,
|
||||
TSF_GET_FAIL,
|
||||
TSF_RESET_GPIO_FAIL,
|
||||
TSF_SAP_NOT_STARTED_NO_TSF
|
||||
TSF_SAP_NOT_STARTED_NO_TSF,
|
||||
TSF_NOT_READY
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -61,19 +63,81 @@ enum hdd_tsf_capture_state {
|
|||
};
|
||||
|
||||
#ifdef WLAN_FEATURE_TSF
|
||||
/**
|
||||
* wlan_hdd_tsf_init() - set gpio and callbacks for
|
||||
* capturing tsf and init tsf_plus
|
||||
* @hdd_ctx: pointer to the hdd_context_t
|
||||
*
|
||||
* This function set the callback to sme module, the callback will be
|
||||
* called when a tsf event is reported by firmware; set gpio number
|
||||
* to FW, FW will toggle this gpio when received a CAP_TSF command;
|
||||
* do tsf_plus init
|
||||
*
|
||||
* Return: nothing
|
||||
*/
|
||||
void wlan_hdd_tsf_init(struct hdd_context_s *hdd_ctx);
|
||||
|
||||
/**
|
||||
* wlan_hdd_tsf_deinit() - reset callbacks for capturing tsf, deinit tsf_plus
|
||||
* @hdd_ctx: pointer to the hdd_context_t
|
||||
*
|
||||
* This function reset the callback to sme module, and deinit tsf_plus
|
||||
*
|
||||
* Return: nothing
|
||||
*/
|
||||
void wlan_hdd_tsf_deinit(hdd_context_t *hdd_ctx);
|
||||
|
||||
/**
|
||||
* hdd_capture_tsf() - capture tsf
|
||||
* @adapter: pointer to adapter
|
||||
* @buf: pointer to uplayer buf
|
||||
* @len : the length of buf
|
||||
*
|
||||
* This function returns tsf value to uplayer.
|
||||
*
|
||||
* Return: 0 for success or non-zero negative failure code
|
||||
*/
|
||||
int hdd_capture_tsf(struct hdd_adapter_s *adapter, uint32_t *buf, int len);
|
||||
|
||||
/**
|
||||
* hdd_indicate_tsf() - return tsf to uplayer
|
||||
*
|
||||
* @adapter: pointer to adapter
|
||||
* @buf: pointer to uplayer buf
|
||||
* @len : the length of buf
|
||||
*
|
||||
* This function returns tsf value to uplayer.
|
||||
*
|
||||
* Return: Describe the execute result of this routine
|
||||
*/
|
||||
int hdd_indicate_tsf(struct hdd_adapter_s *adapter, uint32_t *buf, int len);
|
||||
|
||||
/**
|
||||
* wlan_hdd_cfg80211_handle_tsf_cmd(): Setup TSF operations
|
||||
* @wiphy: Pointer to wireless phy
|
||||
* @wdev: Pointer to wireless device
|
||||
* @data: Pointer to data
|
||||
* @data_len: Data length
|
||||
*
|
||||
* Handle TSF SET / GET operation from userspace
|
||||
*
|
||||
* Return: 0 on success, negative errno on failure
|
||||
*/
|
||||
int wlan_hdd_cfg80211_handle_tsf_cmd(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev,
|
||||
const void *data,
|
||||
int data_len);
|
||||
|
||||
int hdd_get_tsf_cb(void *pcb_cxt, struct stsf *ptsf);
|
||||
#else
|
||||
static inline void wlan_hdd_tsf_init(struct hdd_context_s *hdd_ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void wlan_hdd_tsf_deinit(hdd_context_t *hdd_ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int hdd_indicate_tsf(struct hdd_adapter_s *adapter, uint32_t *buf,
|
||||
int len)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8483,35 +8483,6 @@ static void hdd_initialize_mac_address(hdd_context_t *hdd_ctx)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_tsf_init() - Initialize the TSF synchronization interface
|
||||
* @hdd_ctx: HDD global context
|
||||
*
|
||||
* When TSF synchronization via GPIO is supported by the driver and
|
||||
* has been enabled in the configuration file, this function plumbs
|
||||
* the GPIO value down to firmware via SME.
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
#ifdef WLAN_FEATURE_TSF
|
||||
static void hdd_tsf_init(hdd_context_t *hdd_ctx)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
|
||||
if (hdd_ctx->config->tsf_gpio_pin == TSF_GPIO_PIN_INVALID)
|
||||
return;
|
||||
|
||||
status = sme_set_tsf_gpio(hdd_ctx->hHal,
|
||||
hdd_ctx->config->tsf_gpio_pin);
|
||||
if (!QDF_IS_STATUS_SUCCESS(status))
|
||||
hdd_err("Set tsf GPIO failed, status: %d", status);
|
||||
}
|
||||
#else
|
||||
static void hdd_tsf_init(hdd_context_t *hdd_ctx)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static int hdd_set_smart_chainmask_enabled(hdd_context_t *hdd_ctx)
|
||||
{
|
||||
int vdev_id = 0;
|
||||
|
|
@ -8899,7 +8870,7 @@ static int hdd_features_init(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter)
|
|||
if (!QDF_IS_STATUS_SUCCESS(status))
|
||||
hdd_err("Error setting txlimit in sme: %d", status);
|
||||
|
||||
hdd_tsf_init(hdd_ctx);
|
||||
wlan_hdd_tsf_init(hdd_ctx);
|
||||
|
||||
ret = hdd_register_cb(hdd_ctx);
|
||||
if (ret) {
|
||||
|
|
@ -8945,9 +8916,21 @@ out:
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_features_deinit() - Deinit features
|
||||
* @hdd_ctx: HDD context
|
||||
*
|
||||
* De-Initialize features and their feature context.
|
||||
*
|
||||
* Return: none.
|
||||
*/
|
||||
static void hdd_features_deinit(hdd_context_t *hdd_ctx)
|
||||
{
|
||||
wlan_hdd_tsf_deinit(hdd_ctx);
|
||||
}
|
||||
|
||||
#ifdef NAPIER_SCAN
|
||||
/**
|
||||
*
|
||||
* hdd_post_cds_enable_config() - HDD post cds start config helper
|
||||
* @adapter - Pointer to the HDD
|
||||
*
|
||||
|
|
@ -9055,6 +9038,10 @@ static int hdd_deconfigure_cds(hdd_context_t *hdd_ctx)
|
|||
int ret = 0;
|
||||
|
||||
ENTER();
|
||||
|
||||
/* De-init features */
|
||||
hdd_features_deinit(hdd_ctx);
|
||||
|
||||
/* De-register the SME callbacks */
|
||||
hdd_deregister_cb(hdd_ctx);
|
||||
|
||||
|
|
|
|||
|
|
@ -36,72 +36,65 @@
|
|||
|
||||
static struct completion tsf_sync_get_completion_evt;
|
||||
#define WLAN_TSF_SYNC_GET_TIMEOUT 2000
|
||||
|
||||
/**
|
||||
* hdd_capture_tsf() - capture tsf
|
||||
* @adapter: pointer to adapter
|
||||
* @buf: pointer to uplayer buf
|
||||
* @len : the length of buf
|
||||
* enum hdd_tsf_op_result - result of tsf operation
|
||||
*
|
||||
* This function returns tsf value to uplayer.
|
||||
*
|
||||
* Return: 0 for success or non-zero negative failure code
|
||||
* HDD_TSF_OP_SUCC: succeed
|
||||
* HDD_TSF_OP_FAIL: fail
|
||||
*/
|
||||
int hdd_capture_tsf(struct hdd_adapter_s *adapter, uint32_t *buf, int len)
|
||||
enum hdd_tsf_op_result {
|
||||
HDD_TSF_OP_SUCC,
|
||||
HDD_TSF_OP_FAIL
|
||||
};
|
||||
|
||||
static
|
||||
enum hdd_tsf_get_state hdd_tsf_check_conn_state(hdd_adapter_t *adapter)
|
||||
{
|
||||
int ret = 0;
|
||||
enum hdd_tsf_get_state ret = TSF_RETURN;
|
||||
hdd_station_ctx_t *hdd_sta_ctx;
|
||||
|
||||
if (adapter == NULL || buf == NULL) {
|
||||
hdd_err("invalid pointer");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (len != 1)
|
||||
return -EINVAL;
|
||||
|
||||
/* Reset TSF value for new capture */
|
||||
adapter->tsf_high = 0;
|
||||
adapter->tsf_low = 0;
|
||||
adapter->tsf_sync_soc_timer = 0;
|
||||
|
||||
if (adapter->device_mode == QDF_STA_MODE ||
|
||||
adapter->device_mode == QDF_P2P_CLIENT_MODE) {
|
||||
adapter->device_mode == QDF_P2P_CLIENT_MODE) {
|
||||
hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
|
||||
if (hdd_sta_ctx->conn_info.connState !=
|
||||
eConnectionState_Associated) {
|
||||
hdd_err("failed to cap tsf, not connect with ap");
|
||||
buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
|
||||
return ret;
|
||||
ret = TSF_STA_NOT_CONNECTED_NO_TSF;
|
||||
}
|
||||
}
|
||||
if ((adapter->device_mode == QDF_SAP_MODE ||
|
||||
adapter->device_mode == QDF_P2P_GO_MODE) &&
|
||||
!(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
|
||||
} else if ((adapter->device_mode == QDF_SAP_MODE ||
|
||||
adapter->device_mode == QDF_P2P_GO_MODE) &&
|
||||
!(test_bit(SOFTAP_BSS_STARTED,
|
||||
&adapter->event_flags))) {
|
||||
hdd_err("Soft AP / P2p GO not beaconing");
|
||||
buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
|
||||
return ret;
|
||||
}
|
||||
if (adapter->tsf_state == TSF_CAP_STATE) {
|
||||
hdd_err("current in capture state, pls reset");
|
||||
buf[0] = TSF_CURRENT_IN_CAP_STATE;
|
||||
} else {
|
||||
hdd_info("Send TSF capture to FW");
|
||||
buf[0] = TSF_RETURN;
|
||||
adapter->tsf_state = TSF_CAP_STATE;
|
||||
init_completion(&tsf_sync_get_completion_evt);
|
||||
ret = wma_cli_set_command((int)adapter->sessionId,
|
||||
(int)GEN_PARAM_CAPTURE_TSF,
|
||||
adapter->sessionId,
|
||||
GEN_CMD);
|
||||
|
||||
if (ret != QDF_STATUS_SUCCESS) {
|
||||
hdd_err("capture fail");
|
||||
buf[0] = TSF_CAPTURE_FAIL;
|
||||
adapter->tsf_state = TSF_IDLE;
|
||||
}
|
||||
ret = TSF_SAP_NOT_STARTED_NO_TSF;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool hdd_tsf_is_initialized(hdd_adapter_t *adapter)
|
||||
{
|
||||
hdd_context_t *hddctx;
|
||||
|
||||
if (!adapter) {
|
||||
hdd_err("invalid adapter");
|
||||
return false;
|
||||
}
|
||||
|
||||
hddctx = WLAN_HDD_GET_CTX(adapter);
|
||||
if (!hddctx) {
|
||||
hdd_err("invalid hdd context");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!qdf_atomic_read(&hddctx->tsf_ready_flag)) {
|
||||
hdd_err("TSF is not initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_tsf_reset_gpio() - Reset TSF GPIO used for host timer sync
|
||||
* @adapter: pointer to adapter
|
||||
|
|
@ -136,60 +129,137 @@ static int hdd_tsf_reset_gpio(struct hdd_adapter_s *adapter)
|
|||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* hdd_indicate_tsf() - return tsf to uplayer
|
||||
* @adapter: pointer to adapter
|
||||
* @buf: pointer to uplayer buf
|
||||
* @len : the length of buf
|
||||
*
|
||||
* This function returns tsf value to upper layer.
|
||||
*
|
||||
* Return: 0 for success or non-zero negative failure code
|
||||
*/
|
||||
int hdd_indicate_tsf(struct hdd_adapter_s *adapter, uint32_t *buf, int len)
|
||||
static enum hdd_tsf_op_result hdd_capture_tsf_internal(
|
||||
hdd_adapter_t *adapter, uint32_t *buf, int len)
|
||||
{
|
||||
hdd_station_ctx_t *hdd_sta_ctx;
|
||||
int ret;
|
||||
hdd_context_t *hddctx;
|
||||
|
||||
if (adapter == NULL || buf == NULL) {
|
||||
hdd_err("invalid pointer");
|
||||
return -EINVAL;
|
||||
return HDD_TSF_OP_FAIL;
|
||||
}
|
||||
|
||||
if (len != 1)
|
||||
return HDD_TSF_OP_FAIL;
|
||||
|
||||
hddctx = WLAN_HDD_GET_CTX(adapter);
|
||||
if (!hddctx) {
|
||||
hdd_err("invalid hdd context");
|
||||
return HDD_TSF_OP_FAIL;
|
||||
}
|
||||
|
||||
if (!hdd_tsf_is_initialized(adapter)) {
|
||||
buf[0] = TSF_NOT_READY;
|
||||
return HDD_TSF_OP_SUCC;
|
||||
}
|
||||
|
||||
buf[0] = hdd_tsf_check_conn_state(adapter);
|
||||
if (buf[0] != TSF_RETURN)
|
||||
return HDD_TSF_OP_SUCC;
|
||||
|
||||
if (qdf_atomic_inc_return(&hddctx->cap_tsf_flag) > 1) {
|
||||
hdd_err("current in capture state");
|
||||
buf[0] = TSF_CURRENT_IN_CAP_STATE;
|
||||
return HDD_TSF_OP_SUCC;
|
||||
}
|
||||
|
||||
/* record adapter for cap_tsf_irq_handler */
|
||||
hddctx->cap_tsf_context = adapter;
|
||||
|
||||
hdd_err("+ioctl issue cap tsf cmd");
|
||||
|
||||
/* Reset TSF value for new capture */
|
||||
adapter->cur_target_time = 0;
|
||||
|
||||
buf[0] = TSF_RETURN;
|
||||
init_completion(&tsf_sync_get_completion_evt);
|
||||
ret = wma_cli_set_command((int)adapter->sessionId,
|
||||
(int)GEN_PARAM_CAPTURE_TSF,
|
||||
adapter->sessionId, GEN_CMD);
|
||||
if (QDF_STATUS_SUCCESS != ret) {
|
||||
hdd_err("cap tsf fail");
|
||||
buf[0] = TSF_CAPTURE_FAIL;
|
||||
hddctx->cap_tsf_context = NULL;
|
||||
qdf_atomic_set(&hddctx->cap_tsf_flag, 0);
|
||||
return HDD_TSF_OP_SUCC;
|
||||
}
|
||||
hdd_err("-ioctl return cap tsf cmd");
|
||||
return HDD_TSF_OP_SUCC;
|
||||
}
|
||||
|
||||
static enum hdd_tsf_op_result hdd_indicate_tsf_internal(
|
||||
hdd_adapter_t *adapter, uint32_t *buf, int len)
|
||||
{
|
||||
int ret;
|
||||
hdd_context_t *hddctx;
|
||||
|
||||
if (!adapter || !buf) {
|
||||
hdd_err("invalid pointer");
|
||||
return HDD_TSF_OP_FAIL;
|
||||
}
|
||||
|
||||
if (len != 3)
|
||||
return -EINVAL;
|
||||
return HDD_TSF_OP_FAIL;
|
||||
|
||||
hddctx = WLAN_HDD_GET_CTX(adapter);
|
||||
if (!hddctx) {
|
||||
hdd_err("invalid hdd context");
|
||||
return HDD_TSF_OP_FAIL;
|
||||
}
|
||||
|
||||
buf[1] = 0;
|
||||
buf[2] = 0;
|
||||
if (adapter->device_mode == QDF_STA_MODE ||
|
||||
adapter->device_mode == QDF_P2P_CLIENT_MODE) {
|
||||
hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
|
||||
if (hdd_sta_ctx->conn_info.connState !=
|
||||
eConnectionState_Associated) {
|
||||
hdd_info("fail to get tsf, sta in disconnected");
|
||||
buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!hdd_tsf_is_initialized(adapter)) {
|
||||
buf[0] = TSF_NOT_READY;
|
||||
return HDD_TSF_OP_SUCC;
|
||||
}
|
||||
if ((adapter->device_mode == QDF_SAP_MODE ||
|
||||
adapter->device_mode == QDF_P2P_GO_MODE) &&
|
||||
!(test_bit(SOFTAP_BSS_STARTED,
|
||||
&adapter->event_flags))) {
|
||||
hdd_err("Soft AP / P2p GO not beaconing");
|
||||
buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
|
||||
return 0;
|
||||
}
|
||||
if (adapter->tsf_high == 0 && adapter->tsf_low == 0) {
|
||||
|
||||
buf[0] = hdd_tsf_check_conn_state(adapter);
|
||||
if (buf[0] != TSF_RETURN)
|
||||
return HDD_TSF_OP_SUCC;
|
||||
|
||||
if (adapter->cur_target_time == 0) {
|
||||
hdd_info("TSF value not received");
|
||||
buf[0] = TSF_NOT_RETURNED_BY_FW;
|
||||
return HDD_TSF_OP_SUCC;
|
||||
} else {
|
||||
buf[0] = hdd_tsf_reset_gpio(adapter);
|
||||
buf[1] = adapter->tsf_low;
|
||||
buf[2] = adapter->tsf_high;
|
||||
adapter->tsf_state = TSF_IDLE;
|
||||
buf[0] = TSF_RETURN;
|
||||
buf[1] = (uint32_t)(adapter->cur_target_time & 0xffffffff);
|
||||
buf[2] = (uint32_t)((adapter->cur_target_time >> 32) &
|
||||
0xffffffff);
|
||||
|
||||
if (!qdf_atomic_read(&hddctx->cap_tsf_flag)) {
|
||||
hdd_info("old: status=%u, tsf_low=%u, tsf_high=%u",
|
||||
buf[0], buf[1], buf[2]);
|
||||
return HDD_TSF_OP_SUCC;
|
||||
}
|
||||
|
||||
ret = hdd_tsf_reset_gpio(adapter);
|
||||
if (0 != ret) {
|
||||
hdd_err("reset tsf gpio fail");
|
||||
buf[0] = TSF_RESET_GPIO_FAIL;
|
||||
return HDD_TSF_OP_SUCC;
|
||||
}
|
||||
hddctx->cap_tsf_context = NULL;
|
||||
qdf_atomic_set(&hddctx->cap_tsf_flag, 0);
|
||||
hdd_info("get tsf cmd,status=%u, tsf_low=%u, tsf_high=%u",
|
||||
buf[0], buf[1], buf[2]);
|
||||
return HDD_TSF_OP_SUCC;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
|
||||
{
|
||||
return (hdd_capture_tsf_internal(adapter, buf, len) ==
|
||||
HDD_TSF_OP_SUCC) ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
int hdd_indicate_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
|
||||
{
|
||||
return (hdd_indicate_tsf_internal(adapter, buf, len) ==
|
||||
HDD_TSF_OP_SUCC) ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -226,11 +296,17 @@ int hdd_get_tsf_cb(void *pcb_cxt, struct stsf *ptsf)
|
|||
hdd_err("failed to find adapter");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!hdd_tsf_is_initialized(adapter)) {
|
||||
hdd_err("tsf is not init, ignore tsf event");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hdd_info("tsf cb handle event, device_mode is %d",
|
||||
adapter->device_mode);
|
||||
|
||||
adapter->tsf_low = ptsf->tsf_low;
|
||||
adapter->tsf_high = ptsf->tsf_high;
|
||||
adapter->cur_target_time = ((uint64_t)ptsf->tsf_high << 32 |
|
||||
ptsf->tsf_low);
|
||||
adapter->tsf_sync_soc_timer = ((uint64_t) ptsf->soc_timer_high << 32 |
|
||||
ptsf->soc_timer_low);
|
||||
|
||||
|
|
@ -349,8 +425,7 @@ static int __wlan_hdd_cfg80211_handle_tsf_cmd(struct wiphy *wiphy,
|
|||
}
|
||||
if (hdd_wlan_nla_put_u64(reply_skb,
|
||||
QCA_WLAN_VENDOR_ATTR_TSF_TIMER_VALUE,
|
||||
((uint64_t) adapter->tsf_high << 32 |
|
||||
adapter->tsf_low)) ||
|
||||
adapter->cur_target_time) ||
|
||||
hdd_wlan_nla_put_u64(reply_skb,
|
||||
QCA_WLAN_VENDOR_ATTR_TSF_SOC_TIMER_VALUE,
|
||||
adapter->tsf_sync_soc_timer)) {
|
||||
|
|
@ -367,17 +442,6 @@ end:
|
|||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_hdd_cfg80211_handle_tsf_cmd(): Setup TSF operations
|
||||
* @wiphy: Pointer to wireless phy
|
||||
* @wdev: Pointer to wireless device
|
||||
* @data: Pointer to data
|
||||
* @data_len: Data length
|
||||
*
|
||||
* Handle TSF SET / GET operation from userspace
|
||||
*
|
||||
* Return: 0 on success, negative errno on failure
|
||||
*/
|
||||
int wlan_hdd_cfg80211_handle_tsf_cmd(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev,
|
||||
const void *data,
|
||||
|
|
@ -403,5 +467,40 @@ int wlan_hdd_cfg80211_handle_tsf_cmd(struct wiphy *wiphy,
|
|||
*/
|
||||
void wlan_hdd_tsf_init(struct hdd_context_s *hdd_ctx)
|
||||
{
|
||||
sme_set_tsfcb(hdd_ctx->hHal, hdd_get_tsf_cb, hdd_ctx);
|
||||
QDF_STATUS hal_status;
|
||||
|
||||
if (!hdd_ctx)
|
||||
return;
|
||||
|
||||
if (qdf_atomic_inc_return(&hdd_ctx->tsf_ready_flag) > 1)
|
||||
return;
|
||||
|
||||
qdf_atomic_init(&hdd_ctx->cap_tsf_flag);
|
||||
|
||||
if (hdd_ctx->config->tsf_gpio_pin == TSF_GPIO_PIN_INVALID)
|
||||
goto fail;
|
||||
|
||||
hal_status = sme_set_tsf_gpio(hdd_ctx->hHal,
|
||||
hdd_ctx->config->tsf_gpio_pin);
|
||||
if (QDF_STATUS_SUCCESS != hal_status) {
|
||||
hdd_err("set tsf GPIO failed, status: %d", hal_status);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
fail:
|
||||
qdf_atomic_set(&hdd_ctx->tsf_ready_flag, 0);
|
||||
}
|
||||
|
||||
void wlan_hdd_tsf_deinit(hdd_context_t *hdd_ctx)
|
||||
{
|
||||
if (!hdd_ctx)
|
||||
return;
|
||||
|
||||
if (!qdf_atomic_read(&hdd_ctx->tsf_ready_flag))
|
||||
return;
|
||||
|
||||
qdf_atomic_set(&hdd_ctx->tsf_ready_flag, 0);
|
||||
qdf_atomic_set(&hdd_ctx->cap_tsf_flag, 0);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue