qcacld-3.0: get tsf from fw

qcacld-2.0 to qcacld-3.0 propagation

Get tsf from fw. Provide ioctl interface cap_tsf/get_tsf.
Driver issue wmi cmd to fw to realize capture/get.
It can be used in station and softap mode. For sta, getting
tsf from connected ap. For softap, it will generate tsf by-
self

Change-Id: I00d30882bce2f49ee3de3fa189e094c04c0d9943
CRs-Fixed: 817527
这个提交包含在:
Manikandan Mohan
2016-03-15 14:31:56 -07:00
提交者 Vishwajith Upendra
父节点 d9f7a36529
当前提交 dcc21ba7f6
修改 18 个文件,包含 763 行新增26 行删除

8
Kbuild
查看文件

@@ -377,6 +377,10 @@ ifeq ($(CONFIG_QCOM_TDLS),y)
HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_tdls.o
endif
ifeq ($(CONFIG_WLAN_SYNC_TSF),y)
HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_tsf.o
endif
ifeq ($(CONFIG_MPC_UT_FRAMEWORK),y)
HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_conc_ut.o
endif
@@ -1360,6 +1364,10 @@ ifeq ($(CONFIG_LINUX_QCMBR),y)
CDEFINES += -DLINUX_QCMBR
endif
# Enable featue sync tsf between multi devices
ifeq ($(CONFIG_WLAN_SYNC_TSF), y)
CDEFINES += -DWLAN_FEATURE_TSF
endif
# Enable full rx re-order offload for adrastea
ifeq (y, $(filter y, $(CONFIG_CNSS_ADRASTEA) $(CONFIG_ICNSS)))

查看文件

@@ -107,6 +107,10 @@ config WLAN_FEATURE_RX_WAKELOCK
bool "Enable RX wake lock feature"
default n
config WLAN_SYNC_TSF
bool "Enable QCOM sync multi devices tsf feature"
default n
config FEATURE_LFR_SUBNET_DETECTION
bool "Enable LFR Subnet Change Detection"
default n

查看文件

@@ -131,42 +131,43 @@ typedef struct {
* (regardless of the incorrect comment in wireless.h!)
*/
#define QCSAP_IOCTL_SETPARAM (SIOCIWFIRSTPRIV+0)
#define QCSAP_IOCTL_GETPARAM (SIOCIWFIRSTPRIV+1)
#define QCSAP_IOCTL_SETPARAM (SIOCIWFIRSTPRIV + 0)
#define QCSAP_IOCTL_GETPARAM (SIOCIWFIRSTPRIV + 1)
/* (SIOCIWFIRSTPRIV+2) is unused */
/* (SIOCIWFIRSTPRIV+3) is unused */
#define QCSAP_IOCTL_GET_STAWPAIE (SIOCIWFIRSTPRIV+4)
#define QCSAP_IOCTL_SETWPAIE (SIOCIWFIRSTPRIV+5)
#define QCSAP_IOCTL_STOPBSS (SIOCIWFIRSTPRIV+6)
#define QCSAP_IOCTL_VERSION (SIOCIWFIRSTPRIV+7)
#define QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES (SIOCIWFIRSTPRIV+8)
#define QCSAP_IOCTL_GET_CHANNEL (SIOCIWFIRSTPRIV+9)
#define QCSAP_IOCTL_ASSOC_STA_MACADDR (SIOCIWFIRSTPRIV+10)
#define QCSAP_IOCTL_DISASSOC_STA (SIOCIWFIRSTPRIV+11)
#define QCSAP_IOCTL_SET_NONE_GET_THREE (SIOCIWFIRSTPRIV + 3)
#define WE_GET_TSF 1
#define QCSAP_IOCTL_GET_STAWPAIE (SIOCIWFIRSTPRIV + 4)
#define QCSAP_IOCTL_SETWPAIE (SIOCIWFIRSTPRIV + 5)
#define QCSAP_IOCTL_STOPBSS (SIOCIWFIRSTPRIV + 6)
#define QCSAP_IOCTL_VERSION (SIOCIWFIRSTPRIV + 7)
#define QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES (SIOCIWFIRSTPRIV + 8)
#define QCSAP_IOCTL_GET_CHANNEL (SIOCIWFIRSTPRIV + 9)
#define QCSAP_IOCTL_ASSOC_STA_MACADDR (SIOCIWFIRSTPRIV + 10)
#define QCSAP_IOCTL_DISASSOC_STA (SIOCIWFIRSTPRIV + 11)
/* (SIOCIWFIRSTPRIV+12) is unused */
/* Private ioctls and their sub-ioctls */
#define QCSAP_PRIV_GET_CHAR_SET_NONE (SIOCIWFIRSTPRIV + 13)
#define QCSAP_GET_STATS 1
#define QCSAP_LIST_FW_PROFILE 2
#define QCSAP_IOCTL_CLR_STATS (SIOCIWFIRSTPRIV+14)
#define QCSAP_IOCTL_CLR_STATS (SIOCIWFIRSTPRIV + 14)
#define QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE (SIOCIWFIRSTPRIV+15)
#define QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE (SIOCIWFIRSTPRIV + 15)
#define WE_SET_WLAN_DBG 1
#define WE_SET_DP_TRACE 2
#define WE_SET_SAP_CHANNELS 3
#define QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE (SIOCIWFIRSTPRIV+16)
#define QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE (SIOCIWFIRSTPRIV + 16)
#define WE_UNIT_TEST_CMD 7
#define QCSAP_IOCTL_SET_CHANNEL_RANGE (SIOCIWFIRSTPRIV+17)
#define QCSAP_IOCTL_SET_CHANNEL_RANGE (SIOCIWFIRSTPRIV + 17)
#define WE_P2P_NOA_CMD 2
#define QCSAP_IOCTL_MODIFY_ACL (SIOCIWFIRSTPRIV+18)
#define QCSAP_IOCTL_GET_CHANNEL_LIST (SIOCIWFIRSTPRIV+19)
#define QCSAP_IOCTL_SET_TX_POWER (SIOCIWFIRSTPRIV+20)
#define QCSAP_IOCTL_GET_STA_INFO (SIOCIWFIRSTPRIV+21)
#define QCSAP_IOCTL_SET_MAX_TX_POWER (SIOCIWFIRSTPRIV+22)
#define QCSAP_IOCTL_GET_INI_CFG (SIOCIWFIRSTPRIV+25)
#define QCSAP_IOCTL_SET_INI_CFG (SIOCIWFIRSTPRIV+26)
#define QCSAP_IOCTL_MODIFY_ACL (SIOCIWFIRSTPRIV + 18)
#define QCSAP_IOCTL_GET_CHANNEL_LIST (SIOCIWFIRSTPRIV + 19)
#define QCSAP_IOCTL_SET_TX_POWER (SIOCIWFIRSTPRIV + 20)
#define QCSAP_IOCTL_GET_STA_INFO (SIOCIWFIRSTPRIV + 21)
#define QCSAP_IOCTL_SET_MAX_TX_POWER (SIOCIWFIRSTPRIV + 22)
#define QCSAP_IOCTL_GET_INI_CFG (SIOCIWFIRSTPRIV + 25)
#define QCSAP_IOCTL_SET_INI_CFG (SIOCIWFIRSTPRIV + 26)
#define QCSAP_IOCTL_SET_TWO_INT_GET_NONE (SIOCIWFIRSTPRIV + 28)
#ifdef DEBUG
#define QCSAP_IOCTL_SET_FW_CRASH_INJECT 1
@@ -241,7 +242,9 @@ enum {
QCASAP_CLEAR_STATS,
QCASAP_SET_RADAR_DBG,
QCSAP_GET_FW_PROFILE_DATA,
QCSAP_START_FW_PROFILING
QCSAP_START_FW_PROFILING,
QCSAP_CAP_TSF,
QCSAP_GET_TSF,
};
int iw_softap_get_channel_list(struct net_device *dev,

查看文件

@@ -57,6 +57,7 @@
#ifdef FEATURE_WLAN_TDLS
#include "wlan_hdd_tdls.h"
#endif
#include "wlan_hdd_tsf.h"
#include "wlan_hdd_cfg80211.h"
#include <qdf_defer.h>
#ifdef WLAN_FEATURE_MBSSID
@@ -940,6 +941,14 @@ struct hdd_adapter_s {
hdd_ap_ctx_t ap;
} sessionCtx;
#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;
#endif
hdd_cfg80211_state_t cfg80211State;
#ifdef WLAN_FEATURE_PACKET_FILTERING

86
core/hdd/inc/wlan_hdd_tsf.h 普通文件
查看文件

@@ -0,0 +1,86 @@
/*
* Copyright (c) 2016 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/*
* This file was originally distributed by Qualcomm Atheros, Inc.
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
#if !defined WLAN_HDD_TSF_H
#define WLAN_HDD_TSF_H
/**
* enum hdd_tsf_get_state - status of get tsf action
* @TSF_RETURN: get tsf
* @TSF_STA_NOT_CONNECTED_NO_TSF: sta not connected to ap
* @TSF_NOT_RETURNED_BY_FW: fw not returned tsf
* @TSF_CURRENT_IN_CAP_STATE: driver in capture state
* @TSF_CAPTURE_FAIL: capture fail
* @TSF_GET_FAIL: get fail
* @TSF_RESET_GPIO_FAIL: GPIO reset fail
* @TSF_SAP_NOT_STARTED_NO_TSF SAP not started
*/
enum hdd_tsf_get_state {
TSF_RETURN = 0,
TSF_STA_NOT_CONNECTED_NO_TSF,
TSF_NOT_RETURNED_BY_FW,
TSF_CURRENT_IN_CAP_STATE,
TSF_CAPTURE_FAIL,
TSF_GET_FAIL,
TSF_RESET_GPIO_FAIL,
TSF_SAP_NOT_STARTED_NO_TSF
};
/**
* enum hdd_tsf_capture_state - status of capture
* @TSF_IDLE: idle
* @TSF_CAP_STATE: current is in capture state
*/
enum hdd_tsf_capture_state {
TSF_IDLE = 0,
TSF_CAP_STATE
};
#ifdef WLAN_FEATURE_TSF
void wlan_hdd_tsf_init(struct hdd_context_s *hdd_ctx);
int hdd_capture_tsf(struct hdd_adapter_s *adapter, uint32_t *buf, int len);
int hdd_indicate_tsf(struct hdd_adapter_s *adapter, uint32_t *buf, int len);
#else
static inline void wlan_hdd_tsf_init(struct hdd_context_s *hdd_ctx)
{
return;
}
static inline int hdd_indicate_tsf(struct hdd_adapter_s *adapter, uint32_t *buf,
int len)
{
return -ENOTSUPP;
}
static inline int
hdd_capture_tsf(struct hdd_adapter_s *adapter, uint32_t *buf, int len)
{
return -ENOTSUPP;
}
#endif
#endif

查看文件

@@ -75,6 +75,7 @@
#include "qdf_trace.h"
#include "wlan_hdd_cfg.h"
#include "cds_concurrency.h"
#include "wlan_hdd_tsf.h"
#include "wlan_hdd_green_ap.h"
#define IS_UP(_dev) \
@@ -3011,6 +3012,66 @@ static __iw_softap_setparam(struct net_device *dev,
return ret;
}
/**
* __iw_softap_get_three() - return three value to upper layer.
* @dev: pointer of net_device of this wireless card
* @info: meta data about Request sent
* @wrqu: include request info
* @extra: buf used for in/out
*
* Return: execute result
*/
static int __iw_softap_get_three(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
uint32_t *value = (uint32_t *)extra;
uint32_t sub_cmd = value[0];
int ret = 0; /* success */
struct hdd_context_s *hdd_ctx;
struct hdd_adapter_s *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
ret = wlan_hdd_validate_context(hdd_ctx);
if (ret != 0)
return ret;
switch (sub_cmd) {
case QCSAP_GET_TSF:
ret = hdd_indicate_tsf(adapter, value, 3);
break;
default:
hdd_err(FL("Invalid getparam command %d"), sub_cmd);
ret = -EINVAL;
break;
}
return ret;
}
/**
* iw_softap_get_three() - return three value to upper layer.
*
* @dev: pointer of net_device of this wireless card
* @info: meta data about Request sent
* @wrqu: include request info
* @extra: buf used for in/Output
*
* Return: execute result
*/
static int iw_softap_get_three(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
int ret;
cds_ssr_protect(__func__);
ret = __iw_softap_get_three(dev, info, wrqu, extra);
cds_ssr_unprotect(__func__);
return ret;
}
int
static iw_softap_setparam(struct net_device *dev,
struct iw_request_info *info,
@@ -3211,6 +3272,9 @@ static __iw_softap_getparam(struct net_device *dev,
VDEV_CMD);
break;
}
case QCSAP_CAP_TSF:
ret = hdd_capture_tsf(pHostapdAdapter, (uint32_t *)value, 1);
break;
case QCASAP_GET_TEMP_CMD:
{
hddLog(LOG1, "QCASAP_GET_TEMP_CMD");
@@ -5821,6 +5885,15 @@ static const struct iw_priv_args hostapd_private_args[] = {
}, {
QCASAP_NSS_CMD, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
"get_nss"
}, {
QCSAP_CAP_TSF, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
"cap_tsf"
}, {
QCSAP_IOCTL_SET_NONE_GET_THREE, 0, IW_PRIV_TYPE_INT |
IW_PRIV_SIZE_FIXED | 3, ""
}, {
QCSAP_GET_TSF, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
"get_tsf"
}, {
QCASAP_GET_TEMP_CMD, 0,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_temp"
@@ -5997,6 +6070,8 @@ static const iw_handler hostapd_private[] = {
[QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam,
/* get priv ioctl */
[QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam,
[QCSAP_IOCTL_SET_NONE_GET_THREE - SIOCIWFIRSTPRIV] =
iw_softap_get_three,
/* get station genIE */
[QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie,
[QCSAP_IOCTL_SETWPAIE - SIOCIWFIRSTPRIV] = iw_softap_setwpsie,

查看文件

@@ -101,6 +101,7 @@
#include "hif.h"
#include "wma.h"
#include "cds_concurrency.h"
#include "wlan_hdd_tsf.h"
#include "wlan_hdd_green_ap.h"
#include "platform_icnss.h"
#include "bmi.h"
@@ -5963,7 +5964,7 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc)
hdd_rssi_threshold_breached);
hdd_cfg80211_link_layer_stats_init(hdd_ctx);
wlan_hdd_tsf_init(hdd_ctx);
wlan_hdd_send_all_scan_intf_info(hdd_ctx);
wlan_hdd_send_version_pkg(hdd_ctx->target_fw_version,
hdd_ctx->target_hw_version,

227
core/hdd/src/wlan_hdd_tsf.c 普通文件
查看文件

@@ -0,0 +1,227 @@
/*
* Copyright (c) 2016 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/*
* This file was originally distributed by Qualcomm Atheros, Inc.
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
/**
* wlan_hdd_tsf.c - WLAN Host Device Driver tsf related implementation
*/
#include "wlan_hdd_main.h"
#include "wma_api.h"
/**
* 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)
{
int ret = 0;
hdd_station_ctx_t *hdd_sta_ctx;
if (adapter == NULL || buf == NULL) {
hdd_err(FL("invalid pointer"));
return -EINVAL;
}
if (len != 1)
return -EINVAL;
/* Reset TSF value for new capture */
adapter->tsf_high = 0;
adapter->tsf_low = 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_err(FL("failed to cap tsf, not connect with ap"));
buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
return ret;
}
}
if ((adapter->device_mode == QDF_SAP_MODE ||
adapter->device_mode == QDF_P2P_GO_MODE) &&
!(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
hdd_err(FL("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(FL("current in capture state, pls reset"));
buf[0] = TSF_CURRENT_IN_CAP_STATE;
} else {
hdd_info(FL("Send TSF capture to FW"));
buf[0] = TSF_RETURN;
adapter->tsf_state = TSF_CAP_STATE;
ret = wma_cli_set_command((int)adapter->sessionId,
(int)GEN_PARAM_CAPTURE_TSF,
adapter->sessionId,
GEN_CMD);
if (ret != QDF_STATUS_SUCCESS) {
hdd_err(FL("capture fail"));
buf[0] = TSF_CAPTURE_FAIL;
adapter->tsf_state = TSF_IDLE;
}
}
return ret;
}
/**
* 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)
{
int ret = 0;
hdd_station_ctx_t *hdd_sta_ctx;
if (adapter == NULL || buf == NULL) {
hdd_err(FL("invalid pointer"));
return -EINVAL;
}
if (len != 3)
return -EINVAL;
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(FL("fail to get tsf, sta in disconnected"));
buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
return ret;
}
}
if ((adapter->device_mode == QDF_SAP_MODE ||
adapter->device_mode == QDF_P2P_GO_MODE) &&
!(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
hdd_err(FL("Soft AP / P2p GO not beaconing"));
buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
return ret;
}
if (adapter->tsf_high == 0 && adapter->tsf_low == 0) {
hdd_info(FL("TSF value not received"));
buf[0] = TSF_NOT_RETURNED_BY_FW;
} else {
buf[0] = TSF_RETURN;
buf[1] = adapter->tsf_low;
buf[2] = adapter->tsf_high;
adapter->tsf_state = TSF_IDLE;
ret = wma_cli_set_command((int)adapter->sessionId,
(int)GEN_PARAM_RESET_TSF_GPIO,
adapter->sessionId,
GEN_CMD);
if (0 != ret) {
hdd_err(FL("tsf get fail "));
buf[0] = TSF_RESET_GPIO_FAIL;
}
hdd_info(FL("get tsf cmd,status=%u, tsf_low=%u, tsf_high=%u"),
buf[0], buf[1], buf[2]);
}
return ret;
}
/**
* hdd_get_tsf_cb() - handle tsf callback
* @pcb_cxt: pointer to the hdd_contex
* @ptsf: pointer to struct stsf
*
* This function handle the event that reported by firmware at first.
* The event contains the vdev_id, current tsf value of this vdev,
* tsf value is 64bits, discripted in two varaible tsf_low and tsf_high.
* These two values each is uint32.
*
* Return: 0 for success or non-zero negative failure code
*/
static int hdd_get_tsf_cb(void *pcb_cxt, struct stsf *ptsf)
{
struct hdd_context_s *hddctx;
struct hdd_adapter_s *adapter;
int status;
if (pcb_cxt == NULL || ptsf == NULL) {
hdd_err(FL("HDD context is not valid"));
return -EINVAL;
}
hddctx = (struct hdd_context_s *)pcb_cxt;
status = wlan_hdd_validate_context(hddctx);
if (0 != status) {
hdd_err(FL("hdd context is not valid"));
return -EINVAL;
}
adapter = hdd_get_adapter_by_vdev(hddctx, ptsf->vdev_id);
if (NULL == adapter) {
hdd_err(FL("failed to find adapter"));
return -EINVAL;
}
hdd_info(FL("tsf cb handle event, device_mode is %d"),
adapter->device_mode);
adapter->tsf_low = ptsf->tsf_low;
adapter->tsf_high = ptsf->tsf_high;
hdd_info(FL("hdd_get_tsf_cb sta=%u, tsf_low=%u, tsf_high=%u"),
ptsf->vdev_id, ptsf->tsf_low, ptsf->tsf_high);
return 0;
}
/**
* wlan_hdd_tsf_init() - set callback to handle tsf value.
* @hdd_ctx: pointer to the struct hdd_context_s
*
* This function set the callback to sme module, the callback will be
* called when a tsf event is reported by firmware
*
* Return: none
*/
void wlan_hdd_tsf_init(struct hdd_context_s *hdd_ctx)
{
sme_set_tsfcb(hdd_ctx->hHal, hdd_get_tsf_cb, hdd_ctx);
}

查看文件

@@ -80,6 +80,7 @@
#include "sme_power_save_api.h"
#include "cds_concurrency.h"
#include "wlan_hdd_conc_ut.h"
#include "wlan_hdd_tsf.h"
#include "wlan_hdd_ocb.h"
#include "wlan_hdd_napi.h"
#include "cdp_txrx_flow_ctrl_legacy.h"
@@ -273,6 +274,7 @@ static const hdd_freq_chan_map_t freq_chan_map[] = {
#define WE_GET_GTX_MINTPC 53
#define WE_GET_GTX_BWMASK 54
#define WE_GET_TEMPERATURE 56
#define WE_CAP_TSF 58
/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_INT_GET_INT (SIOCIWFIRSTPRIV + 2)
@@ -383,7 +385,8 @@ static const hdd_freq_chan_map_t freq_chan_map[] = {
/* (SIOCIWFIRSTPRIV + 10) is currently unused */
/* (SIOCIWFIRSTPRIV + 12) is currently unused */
/* (SIOCIWFIRSTPRIV + 14) is currently unused */
/* (SIOCIWFIRSTPRIV + 15) is currently unused */
#define WLAN_PRIV_SET_NONE_GET_THREE_INT (SIOCIWFIRSTPRIV + 15)
#define WE_GET_TSF 1
/* (SIOCIWFIRSTPRIV + 16) is currently unused */
/* (SIOCIWFIRSTPRIV + 17) is currently unused */
/* (SIOCIWFIRSTPRIV + 19) is currently unused */
@@ -6298,6 +6301,65 @@ static int iw_setint_getnone(struct net_device *dev,
return ret;
}
/**
* __iw_setnone_get_threeint() - return three value to up layer.
*
* @dev: pointer of net_device of this wireless card
* @info: meta data about Request sent
* @wrqu: include request info
* @extra: buf used for in/Output
*
* Return: execute result
*/
static int __iw_setnone_get_threeint(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
int ret = 0; /* success */
uint32_t *value = (int *)extra;
hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
ENTER_DEV(dev);
ret = wlan_hdd_validate_context(hdd_ctx);
if (0 != ret)
return ret;
hdd_info(FL("param = %d"), value[0]);
switch (value[0]) {
case WE_GET_TSF:
ret = hdd_indicate_tsf(adapter, value, 3);
break;
default:
hdd_err("Invalid IOCTL get_value command %d", value[0]);
break;
}
return ret;
}
/**
* iw_setnone_get_threeint() - return three value to up layer.
*
* @dev: pointer of net_device of this wireless card
* @info: meta data about Request sent
* @wrqu: include request info
* @extra: buf used for in/Output
*
* Return: execute result
*/
static int iw_setnone_get_threeint(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
int ret;
cds_ssr_protect(__func__);
ret = __iw_setnone_get_threeint(dev, info, wrqu, extra);
cds_ssr_unprotect(__func__);
return ret;
}
/**
* iw_setchar_getnone() - Generic "set string" private ioctl handler
* @dev: device upon which the ioctl was received
@@ -6914,7 +6976,9 @@ static int __iw_setnone_getint(struct net_device *dev,
QPOWER_CMD);
break;
}
case WE_CAP_TSF:
ret = hdd_capture_tsf(pAdapter, (uint32_t *)value, 1);
break;
case WE_GET_TEMPERATURE:
{
hddLog(QDF_TRACE_LEVEL_INFO, "WE_GET_TEMPERATURE");
@@ -9809,6 +9873,8 @@ static const iw_handler we_private[] = {
[WLAN_PRIV_SET_NONE_GET_NONE - SIOCIWFIRSTPRIV] = iw_setnone_getnone, /* action priv ioctl */
[WLAN_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] =
iw_hdd_set_var_ints_getnone,
[WLAN_PRIV_SET_NONE_GET_THREE_INT - SIOCIWFIRSTPRIV] =
iw_setnone_get_threeint,
[WLAN_PRIV_ADD_TSPEC - SIOCIWFIRSTPRIV] = iw_add_tspec,
[WLAN_PRIV_DEL_TSPEC - SIOCIWFIRSTPRIV] = iw_del_tspec,
[WLAN_PRIV_GET_TSPEC - SIOCIWFIRSTPRIV] = iw_get_tspec,
@@ -10506,6 +10572,11 @@ static const struct iw_priv_args we_private_args[] = {
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
"get_qnodatapoll"},
{WE_CAP_TSF,
0,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
"cap_tsf"},
{WE_GET_TEMPERATURE,
0,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
@@ -10565,6 +10636,15 @@ static const struct iw_priv_args we_private_args[] = {
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
0,
"setsapchannels"},
/* handlers for main ioctl */
{WLAN_PRIV_SET_NONE_GET_THREE_INT,
0,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
"" },
{WE_GET_TSF,
0,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
"get_tsf" },
{WE_SET_DUAL_MAC_SCAN_CONFIG,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,

查看文件

@@ -5563,6 +5563,21 @@ struct sir_sme_ext_cng_chan_ind {
uint8_t new_channel;
};
/**
* struct stsf - the basic stsf structure
*
* @vdev_id: vdev id
* @tsf_low: low 32bits of tsf
* @tsf_high: high 32bits of tsf
*
* driver use this struct to store the tsf info
*/
struct stsf {
uint32_t vdev_id;
uint32_t tsf_low;
uint32_t tsf_high;
};
/**
* struct egap_params - the enhanced green ap params
* @vdev_id: vdev id

查看文件

@@ -248,6 +248,7 @@ enum eWniMsgTypes {
eWNI_SME_HT40_OBSS_SCAN_IND, /* START and UPDATE OBSS SCAN Indication*/
eWNI_SME_SET_ANTENNA_MODE_REQ,
eWNI_SME_SET_ANTENNA_MODE_RESP,
eWNI_SME_TSF_EVENT,
eWNI_SME_MSG_TYPES_END
};

查看文件

@@ -1096,6 +1096,8 @@ static inline QDF_STATUS sme_send_egap_conf_params(uint32_t enable,
void sme_update_fine_time_measurement_capab(tHalHandle hal, uint32_t val);
QDF_STATUS sme_ht40_stop_obss_scan(tHalHandle hHal, uint32_t vdev_id);
QDF_STATUS sme_set_tsfcb(tHalHandle hHal,
int (*cb_fn)(void *cb_ctx, struct stsf *ptsf), void *cb_ctx);
QDF_STATUS sme_update_mimo_power_save(tHalHandle hHal,
uint8_t is_ht_smps_enabled,

查看文件

@@ -197,6 +197,8 @@ typedef struct tagSmeStruct {
bool enableSelfRecovery;
tCsrLinkStatusCallback linkStatusCallback;
void *linkStatusContext;
int (*get_tsf_cb)(void *pcb_cxt, struct stsf *ptsf);
void *get_tsf_cxt;
/* get temperature event context and callback */
void *pTemperatureCbContext;
void (*pGetTemperatureCb)(int temperature, void *context);

查看文件

@@ -2805,6 +2805,14 @@ QDF_STATUS sme_process_msg(tHalHandle hHal, cds_msg_t *pMsg)
qdf_mem_free(pMsg->bodyptr);
}
break;
case eWNI_SME_TSF_EVENT:
if (pMac->sme.get_tsf_cb) {
pMac->sme.get_tsf_cb(pMac->sme.get_tsf_cxt,
(struct stsf *)pMsg->bodyptr);
}
if (pMsg->bodyptr)
qdf_mem_free(pMsg->bodyptr);
break;
#ifdef WLAN_FEATURE_NAN
case eWNI_SME_NAN_EVENT:
if (pMsg->bodyptr) {
@@ -7300,6 +7308,29 @@ QDF_STATUS sme_preferred_network_found_ind(tHalHandle hHal, void *pMsg)
#endif /* FEATURE_WLAN_SCAN_PNO */
/*
* sme_set_tsfcb() - Set callback for TSF capture
* @hHal: Handler return by macOpen
* @cb_fn: Callback function pointer
* @db_ctx: Callback data
*
* Return: QDF_STATUS
*/
QDF_STATUS sme_set_tsfcb(tHalHandle hHal,
int (*cb_fn)(void *cb_ctx, struct stsf *ptsf), void *cb_ctx)
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
QDF_STATUS status;
status = sme_acquire_global_lock(&pMac->sme);
if (QDF_IS_STATUS_SUCCESS(status)) {
pMac->sme.get_tsf_cb = cb_fn;
pMac->sme.get_tsf_cxt = cb_ctx;
sme_release_global_lock(&pMac->sme);
}
return status;
}
QDF_STATUS sme_get_cfg_valid_channels(tHalHandle hHal, uint8_t *aValidChannels,
uint32_t *len)
{

查看文件

@@ -65,6 +65,8 @@ typedef enum {
GEN_PARAM_DUMP_PCIE_ACCESS_LOG,
#endif
GEN_PARAM_MODULATED_DTIM,
GEN_PARAM_CAPTURE_TSF,
GEN_PARAM_RESET_TSF_GPIO,
} GEN_PARAM;
#define VDEV_CMD 1

查看文件

@@ -1072,6 +1072,10 @@ QDF_STATUS wma_set_auto_shutdown_timer_req(tp_wma_handle wma_handle,
auto_sh_cmd);
#endif
int wma_vdev_tsf_handler(void *handle, uint8_t *data, uint32_t data_len);
QDF_STATUS wma_capture_tsf(tp_wma_handle wma_handle, uint32_t vdev_id);
QDF_STATUS wma_reset_tsf_gpio(tp_wma_handle wma_handle, uint32_t vdev_id);
#ifdef WLAN_FEATURE_NAN
QDF_STATUS wma_nan_req(void *wma_ptr, tpNanRequest nan_req);

查看文件

@@ -267,6 +267,177 @@ end:
wma_post_link_status(pGetLinkStatus, LINK_STATUS_LEGACY);
}
#ifdef WLAN_FEATURE_TSF
/**
* wma_vdev_tsf_handler() - handle tsf event indicated by FW
* @handle: wma context
* @data: event buffer
* @data len: length of event buffer
*
* Return: 0 on success
*/
int wma_vdev_tsf_handler(void *handle, uint8_t *data, uint32_t data_len)
{
cds_msg_t tsf_msg = {0};
WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *param_buf;
wmi_vdev_tsf_report_event_fixed_param *tsf_event;
struct stsf *ptsf;
if (data == NULL) {
WMA_LOGE("%s: invalid pointer", __func__);
return -EINVAL;
}
ptsf = qdf_mem_malloc(sizeof(*ptsf));
if (NULL == ptsf) {
WMA_LOGE("%s: failed to allocate tsf data structure", __func__);
return -ENOMEM;
}
param_buf = (WMI_VDEV_TSF_REPORT_EVENTID_param_tlvs *)data;
tsf_event = param_buf->fixed_param;
ptsf->vdev_id = tsf_event->vdev_id;
ptsf->tsf_low = tsf_event->tsf_low;
ptsf->tsf_high = tsf_event->tsf_high;
WMA_LOGD("%s: receive WMI_VDEV_TSF_REPORT_EVENTID ", __func__);
WMA_LOGD("%s: vdev_id = %u,tsf_low =%u, tsf_high = %u", __func__,
ptsf->vdev_id, ptsf->tsf_low, ptsf->tsf_high);
tsf_msg.type = eWNI_SME_TSF_EVENT;
tsf_msg.bodyptr = ptsf;
tsf_msg.bodyval = 0;
if (QDF_STATUS_SUCCESS !=
cds_mq_post_message(CDS_MQ_ID_SME, &tsf_msg)) {
WMA_LOGP("%s: Failed to post eWNI_SME_TSF_EVENT", __func__);
qdf_mem_free(ptsf);
return -EINVAL;
}
return 0;
}
/**
* wma_capture_tsf() - send wmi to fw to capture tsf
* @wma_handle: wma handler
* @vdev_id: vdev id
*
* Return: wmi send state
*/
QDF_STATUS wma_capture_tsf(tp_wma_handle wma_handle, uint32_t vdev_id)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
wmi_buf_t buf;
wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd;
int ret;
int len = sizeof(*cmd);
buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
if (!buf) {
WMA_LOGP("%s: failed to allocate memory for cap tsf cmd",
__func__);
return QDF_STATUS_E_NOMEM;
}
cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *) wmi_buf_data(buf);
cmd->vdev_id = vdev_id;
cmd->tsf_action = TSF_TSTAMP_CAPTURE_REQ;
WMA_LOGD("%s :vdev_id %u, TSF_TSTAMP_CAPTURE_REQ", __func__,
cmd->vdev_id);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN(
wmi_vdev_tsf_tstamp_action_cmd_fixed_param));
ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
WMI_VDEV_TSF_TSTAMP_ACTION_CMDID);
if (ret != EOK) {
WMA_LOGE("wmi_unified_cmd_send returned Error %d", status);
status = QDF_STATUS_E_FAILURE;
goto error;
}
return QDF_STATUS_SUCCESS;
error:
if (buf)
wmi_buf_free(buf);
return status;
}
/**
* wma_reset_tsf_gpio() - send wmi to fw to reset GPIO
* @wma_handle: wma handler
* @vdev_id: vdev id
*
* Return: wmi send state
*/
QDF_STATUS wma_reset_tsf_gpio(tp_wma_handle wma_handle, uint32_t vdev_id)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
wmi_buf_t buf;
wmi_vdev_tsf_tstamp_action_cmd_fixed_param *cmd;
int ret;
int len = sizeof(*cmd);
uint8_t *buf_ptr;
buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
if (!buf) {
WMA_LOGP("%s: failed to allocate memory for reset tsf gpio",
__func__);
return QDF_STATUS_E_NOMEM;
}
buf_ptr = (uint8_t *) wmi_buf_data(buf);
cmd = (wmi_vdev_tsf_tstamp_action_cmd_fixed_param *) buf_ptr;
cmd->vdev_id = vdev_id;
cmd->tsf_action = TSF_TSTAMP_CAPTURE_RESET;
WMA_LOGD("%s :vdev_id %u, TSF_TSTAMP_CAPTURE_RESET", __func__,
cmd->vdev_id);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN(
wmi_vdev_tsf_tstamp_action_cmd_fixed_param));
ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
WMI_VDEV_TSF_TSTAMP_ACTION_CMDID);
if (ret != EOK) {
WMA_LOGE("wmi_unified_cmd_send returned Error %d", status);
status = QDF_STATUS_E_FAILURE;
goto error;
}
return QDF_STATUS_SUCCESS;
error:
if (buf)
wmi_buf_free(buf);
return status;
}
#else
QDF_STATUS wma_capture_tsf(tp_wma_handle wma_handle, uint32_t vdev_id)
{
return QDF_STATUS_SUCCESS;
}
QDF_STATUS wma_reset_tsf_gpio(tp_wma_handle wma_handle, uint32_t vdev_id)
{
return QDF_STATUS_SUCCESS;
}
int wma_vdev_tsf_handler(void *handle, uint8_t *data, uint32_t data_len)
{
return 0;
}
#endif
#ifdef FEATURE_WLAN_LPHB
/**
* wma_lphb_conf_hbenable() - enable command of LPHB configuration requests

查看文件

@@ -919,6 +919,12 @@ static void wma_process_cli_set_cmd(tp_wma_handle wma,
privcmd->param_value,
privcmd->param_sec_value);
break;
case GEN_PARAM_CAPTURE_TSF:
ret = wma_capture_tsf(wma, privcmd->param_value);
break;
case GEN_PARAM_RESET_TSF_GPIO:
ret = wma_reset_tsf_gpio(wma, privcmd->param_value);
break;
#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG
case GEN_PARAM_DUMP_PCIE_ACCESS_LOG:
htc_dump(wma->htc_handle, PCIE_DUMP, false);
@@ -2755,6 +2761,16 @@ QDF_STATUS wma_start(void *cds_ctx)
goto end;
}
status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
WMI_VDEV_TSF_REPORT_EVENTID,
wma_vdev_tsf_handler,
WMA_RX_SERIALIZER_CTX);
if (0 != status) {
WMA_LOGP("%s: Failed to register tsf callback", __func__);
qdf_status = QDF_STATUS_E_FAILURE;
goto end;
}
/* Initialize the log flush complete event handler */
status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID,