qcacmn: Converge FTM feature

Support for FTM to make it common between WIN and MCL.

Change-Id: I4a65ca6d73d83e71f6a04405b5c41cdddb0a3c71
CRs-fixed: 2148283
This commit is contained in:
akosigi
2017-11-15 18:29:32 +05:30
committed by snandini
parent 3550d5a7f6
commit fffcebf2e9
19 changed files with 1360 additions and 1 deletions

166
ftm/core/src/wlan_ftm_svc.c Normal file
View File

@@ -0,0 +1,166 @@
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
*
* 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.
*/
/**
* DOC: This implementation of init/deint functions for FTM services.
*/
#include "wlan_ftm_svc_i.h"
#include <wlan_lmac_if_def.h>
#include <wlan_ftm_ucfg_api.h>
static inline struct wlan_lmac_if_ftm_tx_ops *
wlan_psoc_get_ftm_txops(struct wlan_objmgr_psoc *psoc)
{
return &((psoc->soc_cb.tx_ops.ftm_tx_ops));
}
static QDF_STATUS
ftm_pdev_obj_init(struct wifi_ftm_pdev_priv_obj *ftm_pdev_obj)
{
ftm_pdev_obj->data = qdf_mem_malloc(FTM_CMD_MAX_BUF_LENGTH);
if (!ftm_pdev_obj->data) {
ftm_err("Memory alloc failed for ftm pdev obj data");
return QDF_STATUS_E_NOMEM;
}
ftm_pdev_obj->length = 0;
ftm_pdev_obj->cmd_type = WIFI_FTM_CMD_UNKNOWN;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
wlan_ftm_pdev_obj_create_notification(struct wlan_objmgr_pdev *pdev,
void *arg_list)
{
QDF_STATUS status;
struct wifi_ftm_pdev_priv_obj *ftm_pdev_obj;
ftm_pdev_obj = qdf_mem_malloc(sizeof(*ftm_pdev_obj));
if (!ftm_pdev_obj) {
ftm_err("Memory alloc failed for ftm pdev obj");
return QDF_STATUS_E_NOMEM;
}
ftm_pdev_obj->pdev = pdev;
status = ftm_pdev_obj_init(ftm_pdev_obj);
if (QDF_IS_STATUS_ERROR(status)) {
ftm_err("ftm pdev obj init failed");
qdf_mem_free(ftm_pdev_obj);
return status;
}
status = wlan_objmgr_pdev_component_obj_attach(pdev,
WLAN_UMAC_COMP_FTM,
ftm_pdev_obj,
QDF_STATUS_SUCCESS);
if (QDF_IS_STATUS_ERROR(status)) {
ftm_err("ftm pdev obj attach failed");
qdf_mem_free(ftm_pdev_obj);
return status;
}
return status;
}
static QDF_STATUS
ftm_pdev_obj_deinit(struct wifi_ftm_pdev_priv_obj *ftm_pdev_obj)
{
if (ftm_pdev_obj->data) {
qdf_mem_free(ftm_pdev_obj->data);
ftm_pdev_obj->data = NULL;
ftm_pdev_obj->length = 0;
}
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
wlan_ftm_pdev_obj_destroy_notification(struct wlan_objmgr_pdev *pdev,
void *arg_list)
{
QDF_STATUS status;
struct wifi_ftm_pdev_priv_obj *ftm_pdev_obj =
wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_FTM);
if (NULL == ftm_pdev_obj) {
ftm_err("invalid wifi ftm obj");
return QDF_STATUS_E_FAULT;
}
status = wlan_objmgr_pdev_component_obj_detach(pdev, WLAN_UMAC_COMP_FTM,
ftm_pdev_obj);
status = ftm_pdev_obj_deinit(ftm_pdev_obj);
ftm_pdev_obj->pdev = NULL;
qdf_mem_free(ftm_pdev_obj);
return status;
}
QDF_STATUS
wlan_ftm_testmode_attach(struct wlan_objmgr_psoc *psoc)
{
struct wlan_lmac_if_ftm_tx_ops *ftm_tx_ops;
ftm_tx_ops = wlan_psoc_get_ftm_txops(psoc);
if (ftm_tx_ops->ftm_attach)
return ftm_tx_ops->ftm_attach(psoc);
else
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
wlan_ftm_testmode_detach(struct wlan_objmgr_psoc *psoc)
{
struct wlan_lmac_if_ftm_tx_ops *ftm_tx_ops;
ftm_tx_ops = wlan_psoc_get_ftm_txops(psoc);
if (ftm_tx_ops->ftm_detach)
return ftm_tx_ops->ftm_detach(psoc);
else
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
wlan_ftm_cmd_send(struct wlan_objmgr_pdev *pdev, uint8_t *buf,
uint32_t len, uint8_t pdev_id)
{
struct wlan_lmac_if_ftm_tx_ops *ftm_tx_ops;
struct wlan_objmgr_psoc *psoc;
psoc = wlan_pdev_get_psoc(pdev);
if (!psoc)
return QDF_STATUS_E_NOENT;
ftm_tx_ops = wlan_psoc_get_ftm_txops(psoc);
if (ftm_tx_ops->ftm_cmd_send)
return ftm_tx_ops->ftm_cmd_send(pdev, buf, len, pdev_id);
return QDF_STATUS_SUCCESS;
}

View File

@@ -0,0 +1,91 @@
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
*
* 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.
*/
/**
* DOC: declare the ftm service data structure and apis
*/
#ifndef _WLAN_FTM_SVC_H_
#define _WLAN_FTM_SVC_H_
#include <qdf_types.h>
#include <qdf_status.h>
#include <wlan_objmgr_pdev_obj.h>
/**
* struct ftm_seg_hdr_info - the segment header for the event from FW
* @len: length of the segment header
* @msgref: message reference
* @segment_info: segment information
* @pad: padding
*
*/
struct ftm_seg_hdr_info {
uint32_t len;
uint32_t msgref;
uint32_t segment_info;
uint32_t pad;
};
/**
* wlan_ftm_pdev_obj_create_notification() - ftm pdev create handler
* @pdev: pdev pointer
* @arg_list: argument list
*
* return: QDF_STATUS_SUCCESS for success or error code
*/
QDF_STATUS wlan_ftm_pdev_obj_create_notification(struct wlan_objmgr_pdev *pdev,
void *arg_list);
/**
* wlan_ftm_pdev_obj_destroy_notification() - ftm pdev destroy handler
* @pdev: pdev pointer
* @arg_list: argument list
*
* return: QDF_STATUS_SUCCESS for success or error code
*/
QDF_STATUS wlan_ftm_pdev_obj_destroy_notification(struct wlan_objmgr_pdev *pdev,
void *arg_list);
/**
* wlan_ftm_cmd_send() - send ftm command to target_if layer
* @pdev: pdev pointer
* @buf: data buffer
* @len: event length
*
* return: QDF_STATUS_SUCCESS for success or error code
*/
QDF_STATUS wlan_ftm_cmd_send(struct wlan_objmgr_pdev *pdev, uint8_t *buf,
uint32_t len, uint8_t pdev_id);
/**
* wlan_ftm_testmode_attach() - Attach FTM UTF handle
* @psoc: psoc pointer
*
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
*/
QDF_STATUS wlan_ftm_testmode_attach(struct wlan_objmgr_psoc *psoc);
/**
* wlan_ftm_testmode_detach() - Attach FTM UTF handle
* @psoc: psoc pointer
*
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
*/
QDF_STATUS wlan_ftm_testmode_detach(struct wlan_objmgr_psoc *psoc);
#endif /* _WLAN_FTM_SVC_H_ */

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
*
* 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.
*/
/**
* DOC: declare the ftm service data structure and apis
*/
#ifndef _WLAN_FTM_UCFG_API_H_
#define _WLAN_FTM_UCFG_API_H_
#include <qdf_types.h>
#include <qdf_status.h>
#include <wlan_objmgr_cmn.h>
/**
* dispatcher_ftm_init() - FTM testmode initialization API
*
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
*/
QDF_STATUS dispatcher_ftm_init(void);
/**
* dispatcher_ftm_deinit() - FTM testmode deinitialization API
*
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
*/
QDF_STATUS dispatcher_ftm_deinit(void);
/**
* dispatcher_ftm_psoc_open() - FTM module open API
* @psoc: psoc object
*
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
*/
QDF_STATUS dispatcher_ftm_psoc_open(struct wlan_objmgr_psoc *psoc);
/**
* dispatcher_ftm_psoc_close() - FTM module close API
* @psoc: psoc object
*
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
*/
QDF_STATUS dispatcher_ftm_psoc_close(struct wlan_objmgr_psoc *psoc);
#endif /* _WLAN_FTM_UCFG_API_H_ */

View File

@@ -0,0 +1,125 @@
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
*
* 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.
*/
/**
* DOC: declare the ftm service data structure and apis
*/
#ifndef _WLAN_FTM_UCFG_API_H_
#define _WLAN_FTM_UCFG_API_H_
#include <qdf_types.h>
#include <qdf_status.h>
#include <wlan_objmgr_cmn.h>
#define FTM_DEBUG 0
#if FTM_DEBUG
#define ftm_log(level, args...) \
QDF_TRACE(QDF_MODULE_ID_FTM, level, ## args)
#define ftm_logfl(level, format, args...) \
ftm_log(level, FL(format), ## args)
#define ftm_alert(format, args...) \
ftm_logfl(QDF_TRACE_LEVEL_FATAL, format, ## args)
#define ftm_err(format, args...) \
ftm_logfl(QDF_TRACE_LEVEL_ERROR, format, ## args)
#define ftm_warn(format, args...) \
ftm_logfl(QDF_TRACE_LEVEL_WARN, format, ## args)
#define ftm_notice(format, args...) \
ftm_logfl(QDF_TRACE_LEVEL_INFO, format, ## args)
#define ftm_debug(format, args...) \
ftm_logfl(QDF_TRACE_LEVEL_DEBUG, format, ## args)
#else
#define ftm_alert(format, args...)
#define ftm_err(format, args...)
#define ftm_warn(format, args...)
#define ftm_notice(format, args...)
#define ftm_debug(format, args...)
#endif
#define FTM_IOCTL_UNIFIED_UTF_CMD 0x1000
#define FTM_IOCTL_UNIFIED_UTF_RSP 0x1001
#define FTM_CMD_MAX_BUF_LENGTH 2048
/**
* enum wifi_ftm_cmd_type - the enumeration of the command source per pdev
* @WIFI_FTM_CMD_IOCTL: command from ioctl on the pdev
* @WIFI_FTM_CMD_NL80211: command from nl80211 on the pdev
*
*/
enum wifi_ftm_pdev_cmd_type {
WIFI_FTM_CMD_IOCTL = 1,
WIFI_FTM_CMD_NL80211,
/* command should be added above */
WIFI_FTM_CMD_UNKNOWN,
};
/**
* struct wifi_ftm_pdev_priv_obj - wifi ftm pdev utf event info
* @pdev: pointer to pdev
* @data: data ptr
* @current_seq: curent squence
* @expected_seq: expected sequence
* @length: length
* @offset: offset
* @cmd_type: command type from either ioctl or nl80211
*/
struct wifi_ftm_pdev_priv_obj {
struct wlan_objmgr_pdev *pdev;
uint8_t *data;
uint8_t current_seq;
uint8_t expected_seq;
qdf_size_t length;
qdf_size_t offset;
enum wifi_ftm_pdev_cmd_type cmd_type;
};
/**
* wlan_ftm_testmode_cmd() - handle FTM testmode command
* @pdev: pdev pointer
* @data: data
* @len: data length
*
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
*/
QDF_STATUS ucfg_wlan_ftm_testmode_cmd(struct wlan_objmgr_pdev *pdev,
uint8_t *data, uint32_t len);
/**
* wlan_ftm_testmode_rsp() - handle FTM testmode command
* @pdev: pdev pointer
* @data: data
*
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
*/
QDF_STATUS ucfg_wlan_ftm_testmode_rsp(struct wlan_objmgr_pdev *pdev,
uint8_t *data);
/**
* wlan_ftm_process_utf_event() - process ftm UTF event
* @scn_handle: scn handle
* @event: event buffer
* @len: event length
*
* return: QDF_STATUS_SUCCESS for success or error code
*/
QDF_STATUS wlan_ftm_process_utf_event(struct wlan_objmgr_pdev *pdev,
uint8_t *event_buf, uint32_t len);
#endif /* _WLAN_FTM_UCFG_API_H_ */

View File

@@ -0,0 +1,85 @@
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
*
* 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.
*/
/**
* DOC: This implementation of init/deint functions for FTM services.
*/
#include <wlan_ftm_init_deinit_api.h>
#include <wlan_ftm_ucfg_api.h>
#include <wlan_objmgr_global_obj.h>
#include "../../core/src/wlan_ftm_svc_i.h"
#include <wlan_cmn.h>
#include <qdf_module.h>
QDF_STATUS dispatcher_ftm_init(void)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
status = wlan_objmgr_register_pdev_create_handler(WLAN_UMAC_COMP_FTM,
wlan_ftm_pdev_obj_create_notification, NULL);
if (QDF_IS_STATUS_ERROR(status))
goto err_pdev_create;
status = wlan_objmgr_register_pdev_destroy_handler(WLAN_UMAC_COMP_FTM,
wlan_ftm_pdev_obj_destroy_notification, NULL);
if (QDF_IS_STATUS_ERROR(status))
goto err_pdev_delete;
return QDF_STATUS_SUCCESS;
err_pdev_delete:
wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_FTM,
wlan_ftm_pdev_obj_create_notification, NULL);
err_pdev_create:
return status;
}
QDF_STATUS dispatcher_ftm_deinit(void)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
status = wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_FTM,
wlan_ftm_pdev_obj_create_notification, NULL);
if (QDF_IS_STATUS_ERROR(status))
return QDF_STATUS_E_FAILURE;
status = wlan_objmgr_unregister_pdev_destroy_handler(WLAN_UMAC_COMP_FTM,
wlan_ftm_pdev_obj_destroy_notification, NULL);
if (QDF_IS_STATUS_ERROR(status))
return QDF_STATUS_E_FAILURE;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS dispatcher_ftm_psoc_open(struct wlan_objmgr_psoc *psoc)
{
/* calling the wmi event handler registration */
return wlan_ftm_testmode_attach(psoc);
}
QDF_STATUS dispatcher_ftm_psoc_close(struct wlan_objmgr_psoc *psoc)
{
/* calling the wmi event handler de-registration */
return wlan_ftm_testmode_detach(psoc);
}

View File

@@ -0,0 +1,139 @@
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
*
* 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.
*/
/**
* DOC: This implementation of init/deint functions for FTM services.
*/
#include <wlan_ftm_ucfg_api.h>
#include <wlan_cfg80211_ftm.h>
#include "../../core/src/wlan_ftm_svc_i.h"
#include <wlan_cmn.h>
#include <qdf_module.h>
QDF_STATUS ucfg_wlan_ftm_testmode_cmd(struct wlan_objmgr_pdev *pdev,
uint8_t *data, uint32_t len)
{
struct wifi_ftm_pdev_priv_obj *ftm_pdev_obj;
uint8_t pdev_id;
ftm_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
WLAN_UMAC_COMP_FTM);
if (!ftm_pdev_obj) {
ftm_err("Failed to get ftm pdev component");
return QDF_STATUS_E_FAILURE;
}
ftm_pdev_obj->length = 0;
pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
return wlan_ftm_cmd_send(pdev, data, len, pdev_id);
}
QDF_STATUS ucfg_wlan_ftm_testmode_rsp(struct wlan_objmgr_pdev *pdev,
uint8_t *data)
{
struct wifi_ftm_pdev_priv_obj *ftm_pdev_obj;
uint32_t *len;
ftm_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
WLAN_UMAC_COMP_FTM);
if (!ftm_pdev_obj) {
ftm_err("Failed to get ftm pdev component");
return QDF_STATUS_E_FAILURE;
}
if (ftm_pdev_obj->length) {
len = (uint32_t *)data;
*len = ftm_pdev_obj->length;
qdf_mem_copy((data + 4), ftm_pdev_obj->data,
ftm_pdev_obj->length);
ftm_pdev_obj->length = 0;
return QDF_STATUS_SUCCESS;
}
return QDF_STATUS_E_FAILURE;
}
QDF_STATUS
wlan_ftm_process_utf_event(struct wlan_objmgr_pdev *pdev,
uint8_t *event_buf, uint32_t len)
{
struct wifi_ftm_pdev_priv_obj *ftm_pdev_obj;
u_int16_t utf_datalen;
uint8_t *utf_data;
struct ftm_seg_hdr_info seghdr_info;
u_int8_t total_segments, current_seq;
ftm_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
WLAN_UMAC_COMP_FTM);
if (!ftm_pdev_obj) {
ftm_err("Failed to get ftm pdev component");
return QDF_STATUS_E_FAILURE;
}
utf_data = event_buf;
seghdr_info = *(struct ftm_seg_hdr_info *)(event_buf);
ftm_pdev_obj->current_seq = (seghdr_info.segment_info & 0xF);
current_seq = (seghdr_info.segment_info & 0xF);
total_segments = (seghdr_info.segment_info >> 4) & 0xF;
utf_datalen = len - sizeof(seghdr_info);
if (current_seq == 0) {
ftm_pdev_obj->expected_seq = 0;
ftm_pdev_obj->offset = 0;
} else {
if (ftm_pdev_obj->expected_seq != current_seq) {
ftm_debug("seq mismatch exp Seq %d got seq %d\n",
ftm_pdev_obj->expected_seq, current_seq);
}
}
qdf_mem_copy(&ftm_pdev_obj->data[ftm_pdev_obj->offset],
&utf_data[sizeof(seghdr_info)], utf_datalen);
ftm_pdev_obj->offset = ftm_pdev_obj->offset + utf_datalen;
ftm_pdev_obj->expected_seq++;
if (ftm_pdev_obj->expected_seq == total_segments) {
if (ftm_pdev_obj->offset != seghdr_info.len) {
ftm_debug("len mismatch len %zu total len %d\n",
ftm_pdev_obj->offset, seghdr_info.len);
}
ftm_pdev_obj->length = ftm_pdev_obj->offset;
/**
* If the repsonse is for a command from FTM daemon,
* send this repsonse data to cfg80211
*/
if (ftm_pdev_obj->cmd_type == WIFI_FTM_CMD_NL80211) {
if (wlan_cfg80211_ftm_rx_event(pdev, ftm_pdev_obj->data,
ftm_pdev_obj->length) != QDF_STATUS_SUCCESS) {
return QDF_STATUS_E_FAILURE;
}
ftm_pdev_obj->cmd_type = WIFI_FTM_CMD_UNKNOWN;
}
}
return QDF_STATUS_SUCCESS;
}

View File

@@ -22,6 +22,7 @@
#include <dispatcher_init_deinit.h>
#include <scheduler_api.h>
#include <wlan_scan_ucfg_api.h>
#include <wlan_ftm_init_deinit_api.h>
#include <wlan_mgmt_txrx_utils_api.h>
#include <wlan_serialization_api.h>
#ifdef WLAN_POLICY_MGR_ENABLE
@@ -774,6 +775,9 @@ QDF_STATUS dispatcher_init(void)
if (QDF_STATUS_SUCCESS != dispatcher_green_ap_init())
goto green_ap_init_fail;
if (QDF_STATUS_SUCCESS != dispatcher_ftm_init())
goto ftm_init_fail;
/*
* scheduler INIT has to be the last as each component's
* initialization has to happen first and then at the end
@@ -785,6 +789,8 @@ QDF_STATUS dispatcher_init(void)
return QDF_STATUS_SUCCESS;
scheduler_init_fail:
dispatcher_ftm_deinit();
ftm_init_fail:
dispatcher_green_ap_deinit();
green_ap_init_fail:
dispatcher_spectral_deinit();
@@ -832,6 +838,8 @@ QDF_STATUS dispatcher_deinit(void)
{
QDF_BUG(QDF_STATUS_SUCCESS == scheduler_deinit());
QDF_BUG(QDF_STATUS_SUCCESS == dispatcher_ftm_deinit());
QDF_BUG(QDF_STATUS_SUCCESS == dispatcher_green_ap_deinit());
QDF_BUG(QDF_STATUS_SUCCESS == dispatcher_spectral_deinit());
@@ -921,7 +929,13 @@ QDF_STATUS dispatcher_psoc_open(struct wlan_objmgr_psoc *psoc)
if (QDF_STATUS_SUCCESS != son_psoc_open(psoc))
goto psoc_son_fail;
if (QDF_STATUS_SUCCESS != dispatcher_ftm_psoc_open(psoc))
goto ftm_psoc_open_fail;
return QDF_STATUS_SUCCESS;
ftm_psoc_open_fail:
son_psoc_close(psoc);
psoc_son_fail:
regulatory_psoc_close(psoc);
regulatory_psoc_open_fail:
@@ -946,6 +960,8 @@ EXPORT_SYMBOL(dispatcher_psoc_open);
QDF_STATUS dispatcher_psoc_close(struct wlan_objmgr_psoc *psoc)
{
QDF_BUG(QDF_STATUS_SUCCESS == dispatcher_ftm_psoc_close(psoc));
QDF_BUG(QDF_STATUS_SUCCESS == son_psoc_close(psoc));
QDF_BUG(QDF_STATUS_SUCCESS == dispatcher_regulatory_psoc_close(psoc));

View File

@@ -0,0 +1,75 @@
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
* 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.
*/
/**
* DOC: declares driver FTM functions interfacing with linux kernel
*/
#ifndef _WLAN_CFG80211_FTM_H_
#define _WLAN_CFG80211_FTM_H_
/**
* enum wlan_cfg80211_ftm_attr - FTM Netlink attributes
* @WLAN_CFG80211_FTM_ATTR_INVALID: attribute is invalid
* @WLAN_CFG80211_FTM_ATTR_CMD: attribute type is FTM command
* @WLAN_CFG80211_FTM_ATTR_DATA: attribute type is data
*
* @WLAN_CFG80211_FTM_ATTR_MAX: Max number of attributes
*/
enum wlan_cfg80211_ftm_attr {
WLAN_CFG80211_FTM_ATTR_INVALID = 0,
WLAN_CFG80211_FTM_ATTR_CMD = 1,
WLAN_CFG80211_FTM_ATTR_DATA = 2,
/* keep last */
WLAN_CFG80211_FTM_ATTR_MAX,
};
/**
* enum wlan_cfg80211_ftm_cmd - FTM command types
* @WLAN_CFG80211_FTM_CMD_WLAN_FTM: command is of type FTM
*/
enum wlan_cfg80211_ftm_cmd {
WLAN_CFG80211_FTM_CMD_WLAN_FTM = 0,
};
#define WLAN_FTM_DATA_MAX_LEN 2048
/**
* wlan_cfg80211_ftm_testmode_cmd() - process cfg80211 testmode command
* @pdev: pdev object
* @data: ftm testmode command data of type void
* @len: length of the data
*
* Return: 0 on success or -Eerrno otherwise
*/
int wlan_cfg80211_ftm_testmode_cmd(struct wlan_objmgr_pdev *pdev,
void *data, uint32_t len);
/**
* wlan_cfg80211_ftm_rx_event() - handle the received ftm event
* @pdev: pdev object
* @data: ftm event data
* @len: length of the data
*
* Return: QDF_STATUS_SUCCESS on success or QDF_STATUS_E errno otherwise
*/
QDF_STATUS wlan_cfg80211_ftm_rx_event(struct wlan_objmgr_pdev *pdev,
uint8_t *data, uint32_t len);
#endif

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
* 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.
*/
/**
* DOC: declares driver FTM functions interfacing with linux kernel
*/
#ifndef _WLAN_IOCTL_FTM_H_
#define _WLAN_IOCTL_FTM_H_
/**
* wlan_ioctl_ftm_testmode_cmd() - handle the ftm ioctl command
* @pdev: pdev object
* @cmd: ftm command
* @userdata: the content of the command
* @length: the length of the userdata
*
* Return: 0 on success, otherwise the error code.
*/
int wlan_ioctl_ftm_testmode_cmd(struct wlan_objmgr_pdev *pdev, int cmd,
uint8_t *userdata, uint32_t length);
#endif

View File

@@ -0,0 +1,154 @@
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
* 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.
*/
/**
* DOC: implementation of the driver FTM functions interfacing with linux kernel
*/
#include <net/cfg80211.h>
#include <qdf_util.h>
#include <wlan_objmgr_pdev_obj.h>
#include <wlan_cfg80211_ftm.h>
#include <wlan_ftm_ucfg_api.h>
#include <wlan_osif_priv.h>
#include <qdf_types.h>
#include <qdf_module.h>
static const struct nla_policy
wlan_cfg80211_ftm_policy[WLAN_CFG80211_FTM_ATTR_MAX + 1] = {
[WLAN_CFG80211_FTM_ATTR_CMD] = {.type = NLA_U32},
[WLAN_CFG80211_FTM_ATTR_DATA] = {.type = NLA_BINARY,
.len = WLAN_FTM_DATA_MAX_LEN},
};
static int
wlan_cfg80211_process_ftm_cmd(struct wlan_objmgr_pdev *pdev,
struct nlattr *tb[])
{
int buf_len;
void *buf;
QDF_STATUS status;
if (!tb[WLAN_CFG80211_FTM_ATTR_DATA]) {
ftm_err("WLAN_CFG80211_FTM_ATTR_DATA attribute is invalid");
return -EINVAL;
}
buf = nla_data(tb[WLAN_CFG80211_FTM_ATTR_DATA]);
buf_len = nla_len(tb[WLAN_CFG80211_FTM_ATTR_DATA]);
if (buf_len > WLAN_FTM_DATA_MAX_LEN)
return -EINVAL;
ftm_debug("****FTM Tx cmd len = %d*****", buf_len);
status = ucfg_wlan_ftm_testmode_cmd(pdev, buf, buf_len);
if (QDF_IS_STATUS_ERROR(status))
status = QDF_STATUS_E_BUSY;
return qdf_status_to_os_return(status);
}
int
wlan_cfg80211_ftm_testmode_cmd(struct wlan_objmgr_pdev *pdev,
void *data, uint32_t len)
{
struct nlattr *tb[WLAN_CFG80211_FTM_ATTR_MAX + 1];
int err = 0, cmd;
struct wifi_ftm_pdev_priv_obj *ftm_pdev_obj;
ftm_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
WLAN_UMAC_COMP_FTM);
if (!ftm_pdev_obj) {
ftm_err("Failed to get ftm pdev component");
return -EINVAL;
}
ftm_pdev_obj->cmd_type = WIFI_FTM_CMD_NL80211;
err = nla_parse(tb, WLAN_CFG80211_FTM_ATTR_MAX - 1, data,
len, wlan_cfg80211_ftm_policy);
if (err) {
ftm_err("Testmode INV ATTR");
return err;
}
if (!tb[WLAN_CFG80211_FTM_ATTR_CMD]) {
ftm_err("Testmode INV CMD");
return -EINVAL;
}
cmd = nla_get_u32(tb[WLAN_CFG80211_FTM_ATTR_CMD]);
switch (cmd) {
case WLAN_CFG80211_FTM_CMD_WLAN_FTM:
err = wlan_cfg80211_process_ftm_cmd(pdev, tb);
break;
default:
ftm_err("unknown command: %d", cmd);
return -ENOENT;
}
return err;
}
qdf_export_symbol(wlan_cfg80211_ftm_testmode_cmd);
QDF_STATUS
wlan_cfg80211_ftm_rx_event(struct wlan_objmgr_pdev *pdev,
uint8_t *data, uint32_t len)
{
struct pdev_osif_priv *pdev_ospriv;
qdf_nbuf_t skb = NULL;
if (!data || !len) {
ftm_err("Null data or invalid length");
return QDF_STATUS_E_INVAL;
}
pdev_ospriv = wlan_pdev_get_ospriv(pdev);
if (!pdev_ospriv) {
ftm_err("pdev_ospriv is NULL");
return QDF_STATUS_E_INVAL;
}
ftm_debug("Testmode response event generated");
skb = cfg80211_testmode_alloc_event_skb(pdev_ospriv->wiphy,
len, GFP_ATOMIC);
if (!skb)
return QDF_STATUS_E_NOMEM;
if (nla_put_u32(skb, WLAN_CFG80211_FTM_ATTR_CMD,
WLAN_CFG80211_FTM_CMD_WLAN_FTM) ||
nla_put(skb, WLAN_CFG80211_FTM_ATTR_DATA, len, data)) {
goto nla_put_failure;
}
cfg80211_testmode_event(skb, GFP_ATOMIC);
return QDF_STATUS_SUCCESS;
nla_put_failure:
qdf_nbuf_free(skb);
ftm_err("nla_put failed on testmode rx skb!");
return QDF_STATUS_E_INVAL;
}

View File

@@ -0,0 +1,115 @@
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
* 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.
*/
/**
* DOC: implementation of the driver FTM functions interfacing with linux kernel
*/
#include <qdf_util.h>
#include <wlan_objmgr_pdev_obj.h>
#include <wlan_ftm_ucfg_api.h>
#include <qdf_types.h>
#include <qdf_module.h>
#include <wlan_cfg80211_ftm.h>
#include <wlan_ioctl_ftm.h>
static QDF_STATUS
wlan_process_ftm_ioctl_cmd(struct wlan_objmgr_pdev *pdev,
uint8_t *userdata, uint32_t length)
{
uint8_t *buffer;
QDF_STATUS error;
if (get_user(length, (uint32_t *)userdata) != 0)
return QDF_STATUS_E_FAILURE;
if (length > WLAN_FTM_DATA_MAX_LEN)
return QDF_STATUS_E_FAILURE;
buffer = qdf_mem_malloc(length);
if (!buffer)
return QDF_STATUS_E_NOMEM;
if (copy_from_user(buffer, &userdata[sizeof(length)], length))
error = QDF_STATUS_E_FAILURE;
else
error = ucfg_wlan_ftm_testmode_cmd(pdev, buffer, length);
qdf_mem_free(buffer);
return error;
}
static QDF_STATUS
wlan_process_ftm_ioctl_rsp(struct wlan_objmgr_pdev *pdev,
uint8_t *userdata, uint32_t length)
{
uint8_t *buffer;
QDF_STATUS error;
length = WLAN_FTM_DATA_MAX_LEN + sizeof(u_int32_t);
buffer = qdf_mem_malloc(length);
if (!buffer)
return QDF_STATUS_E_NOMEM;
error = ucfg_wlan_ftm_testmode_rsp(pdev, buffer);
if (!error)
error = copy_to_user((userdata - sizeof(int)), buffer, length);
else
error = QDF_STATUS_E_AGAIN;
qdf_mem_free(buffer);
return error;
}
int
wlan_ioctl_ftm_testmode_cmd(struct wlan_objmgr_pdev *pdev, int cmd,
uint8_t *userdata, uint32_t length)
{
QDF_STATUS error;
struct wifi_ftm_pdev_priv_obj *ftm_pdev_obj;
ftm_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
WLAN_UMAC_COMP_FTM);
if (!ftm_pdev_obj) {
ftm_err("Failed to get ftm pdev component");
return QDF_STATUS_E_FAILURE;
}
ftm_pdev_obj->cmd_type = WIFI_FTM_CMD_IOCTL;
switch (cmd) {
case FTM_IOCTL_UNIFIED_UTF_CMD:
error = wlan_process_ftm_ioctl_cmd(pdev,
userdata, length);
break;
case FTM_IOCTL_UNIFIED_UTF_RSP:
error = wlan_process_ftm_ioctl_rsp(pdev,
userdata, length);
break;
default:
ftm_err("FTM Unknown cmd - not supported");
error = QDF_STATUS_E_NOSUPPORT;
}
return qdf_status_to_os_return(error);
}
qdf_export_symbol(wlan_ioctl_ftm_testmode_cmd);

View File

@@ -325,6 +325,7 @@ typedef void (*qdf_timer_func_t)(void *);
* @QDF_MODULE_ID_DIRECT_BUF_RX: Direct Buffer Receive module ID
* @QDF_MODULE_ID_DISA: DISA (encryption test) module ID
* @QDF_MODULE_ID_GREEN_AP: Green AP related logging
* @QDF_MODULE_ID_FTM: FTM module ID
* @QDF_MODULE_ID_ANY: anything
* @QDF_MODULE_ID_MAX: Max place holder module ID
*/
@@ -422,6 +423,7 @@ typedef enum {
QDF_MODULE_ID_DIRECT_BUF_RX,
QDF_MODULE_ID_DISA,
QDF_MODULE_ID_GREEN_AP,
QDF_MODULE_ID_FTM,
QDF_MODULE_ID_ANY,
QDF_MODULE_ID_MAX,
} QDF_MODULE_ID;

View File

@@ -34,6 +34,7 @@
#endif
#include <target_if_reg.h>
#include <target_if_scan.h>
#include <target_if_ftm.h>
#ifdef DFS_COMPONENT_ENABLE
#include <target_if_dfs.h>
#endif
@@ -301,6 +302,12 @@ static void target_if_target_tx_ops_register(
target_is_tgt_type_qca9888;
}
static
void target_if_ftm_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
{
target_if_ftm_register_tx_ops(tx_ops);
}
static
QDF_STATUS target_if_register_umac_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
{
@@ -333,6 +340,8 @@ QDF_STATUS target_if_register_umac_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
target_if_green_ap_tx_ops_register(tx_ops);
target_if_ftm_tx_ops_register(tx_ops);
/* Converged UMAC components to register their TX-ops here */
return QDF_STATUS_SUCCESS;
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
*
* 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.
*/
/**
* DOC: declare the ftm service data structure and apis
*/
#ifndef _TARGET_IF_FTM_H_
#define _TARGET_IF_FTM_H_
#include <qdf_types.h>
#include <qdf_status.h>
#include <wlan_objmgr_psoc_obj.h>
/**
* target_if_ftm_register_tx_ops() - register ftm tx ops
* @tx_ops: tx ops pointer
*
* Register ftm tx ops
*
* Return: QDF_STATUS
*/
QDF_STATUS target_if_ftm_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops);
/**
* target_if_ftm_attach() - Register FW event handler
* @psoc: psoc pointer
*
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
*/
QDF_STATUS
target_if_ftm_attach(struct wlan_objmgr_psoc *psoc);
/**
* target_if_ftm_detach() - De-Register FW event handler
* @psoc: psoc pointer
*
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
*/
QDF_STATUS
target_if_ftm_detach(struct wlan_objmgr_psoc *psoc);
/**
* target_if_ftm_cmd_send() - Send WMI command for FTM requests
* @pdev: pdev pointer
* buf: data to be sent to FW
* len: length of the data
* pdev_id: pdev id
*
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
*/
QDF_STATUS
target_if_ftm_cmd_send(struct wlan_objmgr_pdev *pdev,
uint8_t *buf, uint32_t len, uint8_t pdev_id);
#endif /* _TARGET_IF_FTM_H_ */

View File

@@ -0,0 +1,158 @@
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
*
* 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.
*/
/**
* DOC: offload lmac interface APIs definitions for FTM
*/
#include <qdf_status.h>
#include <target_if_ftm.h>
#include <wmi_unified_priv.h>
#include <wlan_objmgr_psoc_obj.h>
#include <target_if.h>
#include <wlan_lmac_if_def.h>
#include <wlan_ftm_ucfg_api.h>
static inline struct wlan_lmac_if_ftm_rx_ops *
target_if_ftm_get_rx_ops(struct wlan_objmgr_psoc *psoc)
{
return &psoc->soc_cb.rx_ops.ftm_rx_ops;
}
static int
target_if_ftm_process_utf_event(ol_scn_t sc, uint8_t *event_buf, uint32_t len)
{
struct wlan_objmgr_psoc *psoc;
struct wlan_objmgr_pdev *pdev;
struct wmi_host_pdev_utf_event event;
struct wlan_lmac_if_ftm_rx_ops *ftm_rx_ops;
QDF_STATUS status = QDF_STATUS_E_FAILURE;
psoc = target_if_get_psoc_from_scn_hdl(sc);
if (!psoc) {
ftm_err("null psoc");
return QDF_STATUS_E_INVAL;
}
status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_FTM_ID);
if (QDF_IS_STATUS_ERROR(status)) {
ftm_err("unable to get psoc reference");
return QDF_STATUS_E_INVAL;
}
event.datalen = len;
if (wmi_extract_pdev_utf_event(GET_WMI_HDL_FROM_PSOC(psoc),
event_buf, &event) != QDF_STATUS_SUCCESS) {
ftm_err("Extracting utf event failed");
wlan_objmgr_psoc_release_ref(psoc, WLAN_FTM_ID);
return QDF_STATUS_E_INVAL;
}
pdev = wlan_objmgr_get_pdev_by_id(psoc, event.pdev_id, WLAN_FTM_ID);
if (!pdev) {
ftm_err("null pdev");
wlan_objmgr_psoc_release_ref(psoc, WLAN_FTM_ID);
return QDF_STATUS_E_INVAL;
}
ftm_rx_ops = target_if_ftm_get_rx_ops(psoc);
if (ftm_rx_ops->ftm_ev_handler) {
status = ftm_rx_ops->ftm_ev_handler(pdev,
event.data, event.datalen);
if (QDF_IS_STATUS_ERROR(status))
status = QDF_STATUS_E_INVAL;
} else {
status = QDF_STATUS_E_INVAL;
}
wlan_objmgr_pdev_release_ref(pdev, WLAN_FTM_ID);
wlan_objmgr_psoc_release_ref(psoc, WLAN_FTM_ID);
return status;
}
QDF_STATUS target_if_ftm_cmd_send(struct wlan_objmgr_pdev *pdev,
uint8_t *buf, uint32_t len, uint8_t pdev_id)
{
QDF_STATUS ret;
wmi_unified_t handle = GET_WMI_HDL_FROM_PDEV(pdev);
struct pdev_utf_params param;
param.utf_payload = buf;
param.len = len;
ret = wmi_unified_pdev_utf_cmd_send(handle, &param, pdev_id);
if (ret) {
ftm_err("wmi utf cmd send failed, ret: %d", ret);
return QDF_STATUS_E_FAILURE;
}
return ret;
}
QDF_STATUS target_if_ftm_attach(struct wlan_objmgr_psoc *psoc)
{
QDF_STATUS ret;
wmi_unified_t handle = GET_WMI_HDL_FROM_PSOC(psoc);
ret = wmi_unified_register_event_handler(handle, wmi_pdev_utf_event_id,
target_if_ftm_process_utf_event,
WMI_RX_UMAC_CTX);
if (ret) {
ftm_err("wmi event registration failed, ret: %d", ret);
return QDF_STATUS_E_FAILURE;
}
return ret;
}
QDF_STATUS target_if_ftm_detach(struct wlan_objmgr_psoc *psoc)
{
int ret;
wmi_unified_t handle = GET_WMI_HDL_FROM_PSOC(psoc);
ret = wmi_unified_unregister_event_handler(handle,
wmi_pdev_utf_event_id);
if (ret) {
ftm_err("wmi event deregistration failed, ret: %d", ret);
return QDF_STATUS_E_FAILURE;
}
return QDF_STATUS_SUCCESS;
}
QDF_STATUS target_if_ftm_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
{
struct wlan_lmac_if_ftm_tx_ops *ftm_tx_ops;
if (!tx_ops) {
ftm_err("invalid tx_ops");
return QDF_STATUS_E_FAILURE;
}
ftm_tx_ops = &tx_ops->ftm_tx_ops;
ftm_tx_ops->ftm_attach = target_if_ftm_attach;
ftm_tx_ops->ftm_detach = target_if_ftm_detach;
ftm_tx_ops->ftm_cmd_send = target_if_ftm_cmd_send;
return QDF_STATUS_SUCCESS;
}

View File

@@ -118,11 +118,13 @@
* @WLAN_UMAC_COMP_NAN: Neighbor Aware Networking
* @WLAN_UMAC_COMP_DFS: DFS
* @WLAN_UMAC_COMP_SPECTRAL: Spectral
* @WLAN_UMAC_COMP_ID_MAX: Maximum components in UMAC
* @WLAN_UMAC_COMP_OFFCHAN_TXRX: Offchan TxRx
* @WLAN_UMAC_COMP_SPLITMAC: SplitMAC
* @WLAN_UMAC_COMP_DISA: DISA encryption test
* @WLAN_UMAC_COMP_GREEN_AP: Green AP
* @WLAN_UMAC_COMP_FTM: FTM component
*
* @WLAN_UMAC_COMP_ID_MAX: Maximum components in UMAC
*
* This id is static.
* On Adding new component, new id has to be assigned
@@ -151,6 +153,7 @@ enum wlan_umac_comp_id {
WLAN_UMAC_COMP_SPLITMAC,
WLAN_UMAC_COMP_DISA,
WLAN_UMAC_COMP_GREEN_AP,
WLAN_UMAC_COMP_FTM,
WLAN_UMAC_COMP_ID_MAX,
};

View File

@@ -203,6 +203,7 @@ typedef void (*wlan_objmgr_peer_status_handler)(
* @WLAN_DEBUG_ID: Debug operations
* @WLAN_DIRECT_BUF_RX_ID: Direct Buffer Receive operations
* @WLAN_DISA_ID: DISA (encryption test) operations
* @WLAN_FTM_ID: FTM module
* @WLAN_REF_ID_MAX: Max id used to generate ref count tracking array
*/
/* New value added to the enum must also be reflected in function
@@ -241,6 +242,7 @@ typedef enum {
WLAN_DEBUG_ID = 29,
WLAN_DIRECT_BUF_RX_ID = 30,
WLAN_DISA_ID = 31,
WLAN_FTM_ID = 31,
WLAN_REF_ID_MAX,
} wlan_objmgr_ref_dbgid;
@@ -286,6 +288,7 @@ static inline char *string_from_dbgid(wlan_objmgr_ref_dbgid id)
"WLAN_DEBUG_ID",
"WLAN_DIRECT_BUF_RX_ID",
"WLAN_DISA_ID",
"WLAN_FTM_ID",
"WLAN_REF_ID_MAX" };
return (char *)strings[id];

View File

@@ -112,6 +112,21 @@ struct wlan_lmac_if_scan_tx_ops {
QDF_STATUS (*set_chan_list)(struct wlan_objmgr_pdev *pdev, void *arg);
};
/**
* struct wlan_lmac_if_ftm_tx_ops - south bound tx function pointers for ftm
* @ftm_attach: function to register event handlers with FW
* @ftm_detach: function to de-register event handlers with FW
* @ftm_cmd_send: function to send FTM commands to FW
*
* ftm module uses these functions to avail ol/da lmac services
*/
struct wlan_lmac_if_ftm_tx_ops {
QDF_STATUS (*ftm_attach)(struct wlan_objmgr_psoc *psoc);
QDF_STATUS (*ftm_detach)(struct wlan_objmgr_psoc *psoc);
QDF_STATUS (*ftm_cmd_send)(struct wlan_objmgr_pdev *pdev,
uint8_t *buf, uint32_t len, uint8_t mac_id);
};
struct wlan_lmac_if_mlme_tx_ops {
void (*scan_sta_power_events)(struct wlan_objmgr_pdev *pdev,
@@ -419,6 +434,17 @@ struct wlan_lmac_if_nan_tx_ops {
};
#endif
/**
* struct wlan_lmac_if_ftm_rx_ops - south bound rx function pointers for FTM
* @ftm_ev_handler: function to handle FTM event
*
* lmac modules uses this API to post FTM events to FTM module
*/
struct wlan_lmac_if_ftm_rx_ops {
QDF_STATUS (*ftm_ev_handler)(struct wlan_objmgr_pdev *pdev,
uint8_t *event_buf, uint32_t len);
};
/**
* struct wlan_lmac_reg_if_tx_ops - structure of tx function
* pointers for regulatory component
@@ -614,15 +640,20 @@ struct wlan_lmac_if_tx_ops {
#endif
struct wlan_lmac_if_mlme_tx_ops mops;
struct wlan_lmac_if_target_tx_ops target_tx_ops;
#ifdef WLAN_OFFCHAN_TXRX_ENABLE
struct wlan_lmac_if_offchan_txrx_ops offchan_txrx_ops;
#endif
#ifdef DIRECT_BUF_RX_ENABLE
struct wlan_lmac_if_direct_buf_rx_tx_ops dbr_tx_ops;
#endif
#ifdef WLAN_SUPPORT_GREEN_AP
struct wlan_lmac_if_green_ap_tx_ops green_ap_tx_ops;
#endif
struct wlan_lmac_if_ftm_tx_ops ftm_tx_ops;
};
/**
@@ -1066,9 +1097,12 @@ struct wlan_lmac_if_rx_ops {
struct wlan_lmac_if_tdls_rx_ops tdls_rx_ops;
#endif
struct wlan_lmac_if_mlme_rx_ops mops;
#ifdef WLAN_SUPPORT_GREEN_AP
struct wlan_lmac_if_green_ap_rx_ops green_ap_rx_ops;
#endif
struct wlan_lmac_if_ftm_rx_ops ftm_rx_ops;
};
/* Function pointer to call legacy tx_ops registration in OL/WMA.

View File

@@ -51,10 +51,12 @@
#include <wlan_dfs_tgt_api.h>
#include <wlan_dfs_utils_api.h>
#endif
#ifdef WLAN_SUPPORT_GREEN_AP
#include <wlan_green_ap_api.h>
#include <wlan_green_ap_ucfg_api.h>
#endif
#include <wlan_ftm_ucfg_api.h>
/* Function pointer for OL/WMA specific UMAC tx_ops
* registration.
@@ -324,6 +326,18 @@ wlan_lmac_if_umac_green_ap_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops)
}
#endif
static QDF_STATUS
wlan_lmac_if_umac_ftm_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops)
{
struct wlan_lmac_if_ftm_rx_ops *ftm_rx_ops;
ftm_rx_ops = &rx_ops->ftm_rx_ops;
ftm_rx_ops->ftm_ev_handler = wlan_ftm_process_utf_event;
return QDF_STATUS_SUCCESS;
}
/**
* wlan_lmac_if_umac_rx_ops_register() - UMAC rx handler register
* @rx_ops: Pointer to rx_ops structure to be populated
@@ -389,6 +403,9 @@ wlan_lmac_if_umac_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops)
wlan_lmac_if_umac_green_ap_rx_ops_register(rx_ops);
/* FTM rx_ops */
wlan_lmac_if_umac_ftm_rx_ops_register(rx_ops);
return QDF_STATUS_SUCCESS;
}