mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-15 01:01:56 -04:00
qcacld-3.0: Add vendor command for TSF operations
Update TSF feature for vendor command QCA_NL80211_VENDOR_SUBCMD_TSF to support TSF operations. Change-Id: I89abf14b9b7d8ee8fe1c12f7684c87e4dee9bfb0 CRs-fixed: 997799
This commit is contained in:
parent
e4e3a14cf4
commit
5356c2b387
8 changed files with 298 additions and 44 deletions
3
Kbuild
3
Kbuild
|
|
@ -134,6 +134,9 @@ ifeq ($(KERNEL_BUILD), 0)
|
|||
#Flag to enable offload packets feature
|
||||
CONFIG_WLAN_OFFLOAD_PACKETS := y
|
||||
|
||||
#enable TSF get feature
|
||||
CONFIG_WLAN_SYNC_TSF := y
|
||||
|
||||
#Flag to enable memdump feature
|
||||
CONFIG_WLAN_FEATURE_MEMDUMP := y
|
||||
|
||||
|
|
|
|||
|
|
@ -960,6 +960,7 @@ struct hdd_adapter_s {
|
|||
uint32_t tsf_high;
|
||||
/* TSF capture state */
|
||||
enum hdd_tsf_capture_state tsf_state;
|
||||
uint64_t tsf_sync_soc_timer;
|
||||
#endif
|
||||
|
||||
hdd_cfg80211_state_t cfg80211State;
|
||||
|
|
|
|||
|
|
@ -64,6 +64,10 @@ enum hdd_tsf_capture_state {
|
|||
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);
|
||||
int wlan_hdd_cfg80211_handle_tsf_cmd(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev,
|
||||
const void *data,
|
||||
int data_len);
|
||||
#else
|
||||
static inline void wlan_hdd_tsf_init(struct hdd_context_s *hdd_ctx)
|
||||
{
|
||||
|
|
@ -81,6 +85,14 @@ hdd_capture_tsf(struct hdd_adapter_s *adapter, uint32_t *buf, int len)
|
|||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static inline int wlan_hdd_cfg80211_handle_tsf_cmd(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev,
|
||||
const void *data,
|
||||
int data_len)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@
|
|||
#include "wlan_hdd_memdump.h"
|
||||
|
||||
#include "wlan_hdd_ocb.h"
|
||||
#include "wlan_hdd_tsf.h"
|
||||
|
||||
#include "wlan_hdd_subnet_detect.h"
|
||||
|
||||
|
|
@ -1052,6 +1053,12 @@ static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
|
|||
.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
|
||||
},
|
||||
#endif /* WLAN_FEATURE_MEMDUMP */
|
||||
#ifdef WLAN_FEATURE_TSF
|
||||
[QCA_NL80211_VENDOR_SUBCMD_TSF_INDEX] = {
|
||||
.vendor_id = QCA_NL80211_VENDOR_ID,
|
||||
.subcmd = QCA_NL80211_VENDOR_SUBCMD_TSF
|
||||
},
|
||||
#endif
|
||||
[QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE_INDEX] = {
|
||||
.vendor_id = QCA_NL80211_VENDOR_ID,
|
||||
.subcmd = QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE
|
||||
|
|
@ -5550,6 +5557,16 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = {
|
|||
WIPHY_VENDOR_CMD_NEED_RUNNING,
|
||||
.doit = wlan_hdd_cfg80211_set_probable_oper_channel
|
||||
},
|
||||
#ifdef WLAN_FEATURE_TSF
|
||||
{
|
||||
.info.vendor_id = QCA_NL80211_VENDOR_ID,
|
||||
.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TSF,
|
||||
.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
|
||||
WIPHY_VENDOR_CMD_NEED_NETDEV |
|
||||
WIPHY_VENDOR_CMD_NEED_RUNNING,
|
||||
.doit = wlan_hdd_cfg80211_handle_tsf_cmd
|
||||
},
|
||||
#endif
|
||||
#ifdef FEATURE_WLAN_TDLS
|
||||
{
|
||||
.info.vendor_id = QCA_NL80211_VENDOR_ID,
|
||||
|
|
|
|||
|
|
@ -258,6 +258,7 @@ typedef enum {
|
|||
* @QCA_NL80211_VENDOR_SUBCMD_GW_PARAM_CONFIG: set gateway parameters
|
||||
* @QCA_NL80211_VENDOR_SUBCMD_SET_TXPOWER_SCALE: set tx power by percentage
|
||||
* @QCA_NL80211_VENDOR_SUBCMD_SET_TXPOWER_SCALE_DECR_DB: reduce tx power by DB
|
||||
* @QCA_NL80211_VENDOR_SUBCMD_TSF: TSF operations command
|
||||
*/
|
||||
|
||||
enum qca_nl80211_vendor_subcmds {
|
||||
|
|
@ -377,6 +378,7 @@ enum qca_nl80211_vendor_subcmds {
|
|||
QCA_NL80211_VENDOR_SUBCMD_SET_TXPOWER_SCALE = 109,
|
||||
/* Tx power scaling in db subcommands */
|
||||
QCA_NL80211_VENDOR_SUBCMD_SET_TXPOWER_SCALE_DECR_DB = 115,
|
||||
QCA_NL80211_VENDOR_SUBCMD_TSF = 119,
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -438,6 +440,7 @@ enum qca_nl80211_vendor_subcmds {
|
|||
* vendor scan complete event index
|
||||
* @QCA_NL80211_VENDOR_SUBCMD_GW_PARAM_CONFIG_INDEX:
|
||||
* update gateway parameters index
|
||||
* @QCA_NL80211_VENDOR_SUBCMD_TSF_INDEX: TSF response events index
|
||||
*/
|
||||
|
||||
enum qca_nl80211_vendor_subcmds_index {
|
||||
|
|
@ -507,6 +510,9 @@ enum qca_nl80211_vendor_subcmds_index {
|
|||
QCA_NL80211_VENDOR_SUBCMD_SCAN_INDEX,
|
||||
QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE_INDEX,
|
||||
QCA_NL80211_VENDOR_SUBCMD_GW_PARAM_CONFIG_INDEX,
|
||||
#ifdef WLAN_FEATURE_TSF
|
||||
QCA_NL80211_VENDOR_SUBCMD_TSF_INDEX,
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -2175,6 +2181,38 @@ enum qca_wlan_vendor_attr_packet_filter {
|
|||
QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_AFTER_LAST - 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum qca_vendor_attr_get_tsf: Vendor attributes for TSF capture
|
||||
* @QCA_WLAN_VENDOR_ATTR_TSF_INVALID: Invalid attribute value
|
||||
* @QCA_WLAN_VENDOR_ATTR_TSF_CMD: enum qca_tsf_operation (u32)
|
||||
* @QCA_WLAN_VENDOR_ATTR_TSF_TIMER_VALUE: Unsigned 64 bit TSF timer value
|
||||
* @QCA_WLAN_VENDOR_ATTR_TSF_SOC_TIMER_VALUE: Unsigned 64 bit Synchronized
|
||||
* SOC timer value at TSF capture
|
||||
* @QCA_WLAN_VENDOR_ATTR_TSF_AFTER_LAST: after last
|
||||
* @QCA_WLAN_VENDOR_ATTR_TSF_MAX: Max value
|
||||
*/
|
||||
enum qca_vendor_attr_tsf_cmd {
|
||||
QCA_WLAN_VENDOR_ATTR_TSF_INVALID = 0,
|
||||
QCA_WLAN_VENDOR_ATTR_TSF_CMD,
|
||||
QCA_WLAN_VENDOR_ATTR_TSF_TIMER_VALUE,
|
||||
QCA_WLAN_VENDOR_ATTR_TSF_SOC_TIMER_VALUE,
|
||||
QCA_WLAN_VENDOR_ATTR_TSF_AFTER_LAST,
|
||||
QCA_WLAN_VENDOR_ATTR_TSF_MAX =
|
||||
QCA_WLAN_VENDOR_ATTR_TSF_AFTER_LAST - 1
|
||||
};
|
||||
|
||||
/**
|
||||
* enum qca_tsf_operation: TSF driver commands
|
||||
* @QCA_TSF_CAPTURE: Initiate TSF Capture
|
||||
* @QCA_TSF_GET: Get TSF capture value
|
||||
* @QCA_TSF_SYNC_GET: Initiate TSF capture and return with captured value
|
||||
*/
|
||||
enum qca_tsf_cmd {
|
||||
QCA_TSF_CAPTURE,
|
||||
QCA_TSF_GET,
|
||||
QCA_TSF_SYNC_GET,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum qca_vendor_attr_get_preferred_freq_list - get preferred channel list
|
||||
* @QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_INVALID: invalid value
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@
|
|||
#include "wlan_hdd_main.h"
|
||||
#include "wma_api.h"
|
||||
|
||||
static struct completion tsf_sync_get_completion_evt;
|
||||
#define WLAN_TSF_SYNC_GET_TIMEOUT 2000
|
||||
/**
|
||||
* hdd_capture_tsf() - capture tsf
|
||||
* @adapter: pointer to adapter
|
||||
|
|
@ -48,7 +50,7 @@ int hdd_capture_tsf(struct hdd_adapter_s *adapter, uint32_t *buf, int len)
|
|||
hdd_station_ctx_t *hdd_sta_ctx;
|
||||
|
||||
if (adapter == NULL || buf == NULL) {
|
||||
hdd_err(FL("invalid pointer"));
|
||||
hdd_err("invalid pointer");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (len != 1)
|
||||
|
|
@ -57,14 +59,14 @@ int hdd_capture_tsf(struct hdd_adapter_s *adapter, uint32_t *buf, int len)
|
|||
/* 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) {
|
||||
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"));
|
||||
eConnectionState_Associated) {
|
||||
hdd_err("failed to cap tsf, not connect with ap");
|
||||
buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -72,24 +74,25 @@ int hdd_capture_tsf(struct hdd_adapter_s *adapter, uint32_t *buf, int len)
|
|||
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"));
|
||||
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(FL("current in capture state, pls reset"));
|
||||
buf[0] = TSF_CURRENT_IN_CAP_STATE;
|
||||
hdd_err("current in capture state, pls reset");
|
||||
buf[0] = TSF_CURRENT_IN_CAP_STATE;
|
||||
} else {
|
||||
hdd_info(FL("Send TSF capture to FW"));
|
||||
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(FL("capture fail"));
|
||||
hdd_err("capture fail");
|
||||
buf[0] = TSF_CAPTURE_FAIL;
|
||||
adapter->tsf_state = TSF_IDLE;
|
||||
}
|
||||
|
|
@ -97,6 +100,39 @@ int hdd_capture_tsf(struct hdd_adapter_s *adapter, uint32_t *buf, int len)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_tsf_reset_gpio() - Reset TSF GPIO used for host timer sync
|
||||
* @adapter: pointer to adapter
|
||||
*
|
||||
* This function send WMI command to reset GPIO configured in FW after
|
||||
* TSF get operation.
|
||||
*
|
||||
* Return: TSF_RETURN on Success, TSF_RESET_GPIO_FAIL on failure
|
||||
*/
|
||||
#ifdef QCA_WIFI_3_0
|
||||
int hdd_tsf_reset_gpio(struct hdd_adapter_s *adapter)
|
||||
{
|
||||
/* No GPIO Host timer sync for integrated WIFI Device */
|
||||
return TSF_RETURN;
|
||||
}
|
||||
#else
|
||||
int hdd_tsf_reset_gpio(struct hdd_adapter_s *adapter)
|
||||
{
|
||||
int ret;
|
||||
ret = wma_cli_set_command((int)adapter->sessionId,
|
||||
(int)GEN_PARAM_RESET_TSF_GPIO, adapter->sessionId,
|
||||
GEN_CMD);
|
||||
|
||||
if (ret != 0) {
|
||||
hdd_err("tsf reset GPIO fail ");
|
||||
ret = TSF_RESET_GPIO_FAIL;
|
||||
} else {
|
||||
ret = TSF_RETURN;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* hdd_indicate_tsf() - return tsf to uplayer
|
||||
* @adapter: pointer to adapter
|
||||
|
|
@ -109,11 +145,10 @@ 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)
|
||||
{
|
||||
int ret = 0;
|
||||
hdd_station_ctx_t *hdd_sta_ctx;
|
||||
|
||||
if (adapter == NULL || buf == NULL) {
|
||||
hdd_err(FL("invalid pointer"));
|
||||
hdd_err("invalid pointer");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -126,42 +161,32 @@ int hdd_indicate_tsf(struct hdd_adapter_s *adapter, uint32_t *buf, int len)
|
|||
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"));
|
||||
eConnectionState_Associated) {
|
||||
hdd_info("fail to get tsf, sta in disconnected");
|
||||
buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
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"));
|
||||
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;
|
||||
return 0;
|
||||
}
|
||||
if (adapter->tsf_high == 0 && adapter->tsf_low == 0) {
|
||||
hdd_info(FL("TSF value not received"));
|
||||
hdd_info("TSF value not received");
|
||||
buf[0] = TSF_NOT_RETURNED_BY_FW;
|
||||
} else {
|
||||
buf[0] = TSF_RETURN;
|
||||
buf[0] = hdd_tsf_reset_gpio(adapter);
|
||||
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"),
|
||||
hdd_info("get tsf cmd,status=%u, tsf_low=%u, tsf_high=%u",
|
||||
buf[0], buf[1], buf[2]);
|
||||
}
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -183,35 +208,183 @@ static int hdd_get_tsf_cb(void *pcb_cxt, struct stsf *ptsf)
|
|||
int status;
|
||||
|
||||
if (pcb_cxt == NULL || ptsf == NULL) {
|
||||
hdd_err(FL("HDD context is not valid"));
|
||||
hdd_err("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"));
|
||||
hdd_err("failed to find adapter");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hdd_info(FL("tsf cb handle event, device_mode is %d"),
|
||||
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->tsf_sync_soc_timer = ((uint64_t) ptsf->soc_timer_high << 32 |
|
||||
ptsf->soc_timer_low);
|
||||
|
||||
hdd_info(FL("hdd_get_tsf_cb sta=%u, tsf_low=%u, tsf_high=%u"),
|
||||
ptsf->vdev_id, ptsf->tsf_low, ptsf->tsf_high);
|
||||
complete(&tsf_sync_get_completion_evt);
|
||||
hdd_info("Vdev=%u, tsf_low=%u, tsf_high=%u soc_timer=%llu",
|
||||
ptsf->vdev_id, ptsf->tsf_low, ptsf->tsf_high,
|
||||
adapter->tsf_sync_soc_timer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* __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
|
||||
*/
|
||||
static int __wlan_hdd_cfg80211_handle_tsf_cmd(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev,
|
||||
const void *data,
|
||||
int data_len)
|
||||
{
|
||||
struct net_device *dev = wdev->netdev;
|
||||
hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
|
||||
hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
|
||||
struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_TSF_MAX + 1];
|
||||
int status, ret;
|
||||
struct sk_buff *reply_skb;
|
||||
uint32_t tsf_op_resp[3], tsf_cmd;
|
||||
|
||||
ENTER_DEV(wdev->netdev);
|
||||
|
||||
status = wlan_hdd_validate_context(hdd_ctx);
|
||||
if (0 != status)
|
||||
return -EINVAL;
|
||||
|
||||
if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_TSF_MAX, data,
|
||||
data_len, NULL)) {
|
||||
hdd_err("Invalid TSF cmd");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_TSF_CMD]) {
|
||||
hdd_err("Invalid TSF cmd");
|
||||
return -EINVAL;
|
||||
}
|
||||
tsf_cmd = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_TSF_CMD]);
|
||||
|
||||
if (tsf_cmd == QCA_TSF_CAPTURE || tsf_cmd == QCA_TSF_SYNC_GET) {
|
||||
hdd_capture_tsf(adapter, tsf_op_resp, 1);
|
||||
switch (tsf_op_resp[0]) {
|
||||
case TSF_RETURN:
|
||||
status = 0;
|
||||
break;
|
||||
case TSF_CURRENT_IN_CAP_STATE:
|
||||
status = -EALREADY;
|
||||
break;
|
||||
case TSF_STA_NOT_CONNECTED_NO_TSF:
|
||||
case TSF_SAP_NOT_STARTED_NO_TSF:
|
||||
status = -EPERM;
|
||||
break;
|
||||
default:
|
||||
case TSF_CAPTURE_FAIL:
|
||||
status = -EINVAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (status < 0)
|
||||
goto end;
|
||||
|
||||
if (tsf_cmd == QCA_TSF_SYNC_GET) {
|
||||
ret = wait_for_completion_timeout(&tsf_sync_get_completion_evt,
|
||||
msecs_to_jiffies(WLAN_TSF_SYNC_GET_TIMEOUT));
|
||||
if (ret == 0) {
|
||||
status = -ETIMEDOUT;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (tsf_cmd == QCA_TSF_GET || tsf_cmd == QCA_TSF_SYNC_GET) {
|
||||
hdd_indicate_tsf(adapter, tsf_op_resp, 3);
|
||||
switch (tsf_op_resp[0]) {
|
||||
case TSF_RETURN:
|
||||
status = 0;
|
||||
break;
|
||||
case TSF_NOT_RETURNED_BY_FW:
|
||||
status = -EINPROGRESS;
|
||||
break;
|
||||
case TSF_STA_NOT_CONNECTED_NO_TSF:
|
||||
case TSF_SAP_NOT_STARTED_NO_TSF:
|
||||
status = -EPERM;
|
||||
break;
|
||||
default:
|
||||
status = -EINVAL;
|
||||
break;
|
||||
}
|
||||
if (status != 0)
|
||||
goto end;
|
||||
|
||||
reply_skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
|
||||
sizeof(uint64_t) * 2 + NLMSG_HDRLEN,
|
||||
QCA_NL80211_VENDOR_SUBCMD_TSF_INDEX,
|
||||
GFP_KERNEL);
|
||||
if (!reply_skb) {
|
||||
hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
|
||||
status = -ENOMEM;
|
||||
goto end;
|
||||
}
|
||||
if (nla_put_u64(reply_skb, QCA_WLAN_VENDOR_ATTR_TSF_TIMER_VALUE,
|
||||
((uint64_t) adapter->tsf_high << 32 |
|
||||
adapter->tsf_low)) ||
|
||||
nla_put_u64(reply_skb,
|
||||
QCA_WLAN_VENDOR_ATTR_TSF_SOC_TIMER_VALUE,
|
||||
adapter->tsf_sync_soc_timer)){
|
||||
hdd_err("nla put fail");
|
||||
kfree_skb(reply_skb);
|
||||
status = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
status = cfg80211_vendor_cmd_reply(reply_skb);
|
||||
}
|
||||
|
||||
end:
|
||||
hdd_info("TSF operation %d Status: %d", tsf_cmd, status);
|
||||
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,
|
||||
int data_len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
cds_ssr_protect(__func__);
|
||||
ret = __wlan_hdd_cfg80211_handle_tsf_cmd(wiphy, wdev, data, data_len);
|
||||
cds_ssr_unprotect(__func__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_hdd_tsf_init() - set callback to handle tsf value.
|
||||
* @hdd_ctx: pointer to the struct hdd_context_s
|
||||
|
|
|
|||
|
|
@ -5589,6 +5589,8 @@ struct sir_sme_ext_cng_chan_ind {
|
|||
* @vdev_id: vdev id
|
||||
* @tsf_low: low 32bits of tsf
|
||||
* @tsf_high: high 32bits of tsf
|
||||
* @soc_timer_low: low 32bits of synced SOC timer value
|
||||
* @soc_timer_high: high 32bits of synced SOC timer value
|
||||
*
|
||||
* driver use this struct to store the tsf info
|
||||
*/
|
||||
|
|
@ -5596,6 +5598,8 @@ struct stsf {
|
|||
uint32_t vdev_id;
|
||||
uint32_t tsf_low;
|
||||
uint32_t tsf_high;
|
||||
uint32_t soc_timer_low;
|
||||
uint32_t soc_timer_high;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -299,6 +299,8 @@ int wma_vdev_tsf_handler(void *handle, uint8_t *data, uint32_t data_len)
|
|||
ptsf->vdev_id = tsf_event->vdev_id;
|
||||
ptsf->tsf_low = tsf_event->tsf_low;
|
||||
ptsf->tsf_high = tsf_event->tsf_high;
|
||||
ptsf->soc_timer_low = tsf_event->qtimer_low;
|
||||
ptsf->soc_timer_high = tsf_event->qtimer_high;
|
||||
|
||||
WMA_LOGD("%s: receive WMI_VDEV_TSF_REPORT_EVENTID ", __func__);
|
||||
WMA_LOGD("%s: vdev_id = %u,tsf_low =%u, tsf_high = %u", __func__,
|
||||
|
|
@ -318,6 +320,11 @@ int wma_vdev_tsf_handler(void *handle, uint8_t *data, uint32_t data_len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef QCA_WIFI_3_0
|
||||
#define TSF_FW_ACTION_CMD TSF_TSTAMP_QTIMER_CAPTURE_REQ
|
||||
#else
|
||||
#define TSF_FW_ACTION_CMD TSF_TSTAMP_CAPTURE_REQ
|
||||
#endif
|
||||
/**
|
||||
* wma_capture_tsf() - send wmi to fw to capture tsf
|
||||
* @wma_handle: wma handler
|
||||
|
|
@ -342,10 +349,9 @@ QDF_STATUS wma_capture_tsf(tp_wma_handle wma_handle, uint32_t vdev_id)
|
|||
|
||||
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);
|
||||
cmd->tsf_action = TSF_FW_ACTION_CMD;
|
||||
WMA_LOGD("%s :vdev_id %u, tsf_cmd: %d", __func__, cmd->vdev_id,
|
||||
cmd->tsf_action);
|
||||
|
||||
WMITLV_SET_HDR(&cmd->tlv_header,
|
||||
WMITLV_TAG_STRUC_wmi_vdev_tsf_tstamp_action_cmd_fixed_param,
|
||||
|
|
|
|||
Loading…
Reference in a new issue