qcacld-3.0: Add iwpriv interface for Motion detection

iwpriv interface is added for configuring Motion detection
feature specific parameters

Added under flag WLAN_FEATURE_MOTION_DETECTION

Change-Id: Ic20c8c43782cf037317f412962fab4a6928eb0b9
CRs-Fixed: 2376722
This commit is contained in:
Visweswara Tanuku 2019-01-07 16:13:12 +05:30 • committed by nshrivas
commit 633976b5b0
12 changed files with 1026 additions and 5 deletions

View file

@ -1386,6 +1386,10 @@ struct hdd_adapter {
#ifdef WLAN_DEBUGFS
struct hdd_debugfs_file_info csr_file[HDD_DEBUGFS_FILE_ID_MAX];
#endif /* WLAN_DEBUGFS */
#ifdef WLAN_FEATURE_MOTION_DETECTION
bool motion_detection_mode;
#endif /* WLAN_FEATURE_MOTION_DETECTION */
};
#define WLAN_HDD_GET_STATION_CTX_PTR(adapter) (&(adapter)->session.station)
@ -3700,4 +3704,20 @@ void wlan_hdd_send_tcp_param_update_event(struct hdd_context *hdd_ctx,
}
#endif /* MSM_PLATFORM */
#ifdef WLAN_FEATURE_MOTION_DETECTION
/**
* hdd_md_host_evt_cb - Callback for Motion Detection Event
* @ctx: HDD context
* @sir_md_evt: motion detect event
*
* Callback for Motion Detection Event. Re-enables Motion
* Detection again upon event
*
* Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and
* QDF_STATUS_E_FAILURE on failure
*/
QDF_STATUS hdd_md_host_evt_cb(void *ctx, struct sir_md_evt *event);
#endif /* WLAN_FEATURE_MOTION_DETECTION */
#endif /* end #if !defined(WLAN_HDD_MAIN_H) */

View file

@ -12055,6 +12055,53 @@ void hdd_get_nud_stats_cb(void *data, struct rsp_stats *rsp, void *context)
hdd_exit();
}
#ifdef WLAN_FEATURE_MOTION_DETECTION
/**
* hdd_md_host_evt_cb - Callback for Motion Detection Event
* @ctx: HDD context
* @event: motion detect event
*
* Callback for Motion Detection Event. Re-enables Motion
* Detection again upon event
*
* Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and
* QDF_STATUS_E_FAILURE on failure
*/
QDF_STATUS hdd_md_host_evt_cb(void *ctx, struct sir_md_evt *event)
{
struct hdd_adapter *adapter = NULL;
struct hdd_context *hdd_ctx;
QDF_STATUS status;
struct sme_motion_det_en motion_det;
if (!ctx || !event)
return QDF_STATUS_E_INVAL;
hdd_ctx = (struct hdd_context *)ctx;
status = wlan_hdd_validate_context(hdd_ctx);
if (0 != status)
return QDF_STATUS_E_INVAL;
adapter = hdd_get_adapter_by_vdev(hdd_ctx, event->vdev_id);
if (!adapter || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
hdd_err("Invalid adapter or adapter has invalid magic");
return QDF_STATUS_E_INVAL;
}
hdd_debug("Motion Detection CB vdev_id=%u, status=%u",
event->vdev_id, event->status);
if (adapter->motion_detection_mode) {
motion_det.vdev_id = event->vdev_id;
motion_det.enable = 1;
hdd_debug("Motion Detect CB -> Enable Motion Detection again");
sme_motion_det_enable(hdd_ctx->mac_handle, &motion_det);
}
return QDF_STATUS_SUCCESS;
}
#endif /* WLAN_FEATURE_MOTION_DETECTION */
/**
* hdd_register_cb - Register HDD callbacks.
* @hdd_ctx: HDD context
@ -12135,6 +12182,10 @@ int hdd_register_cb(struct hdd_context *hdd_ctx)
if (!QDF_IS_STATUS_SUCCESS(status))
hdd_err("Register tx queue callback failed");
#ifdef WLAN_FEATURE_MOTION_DETECTION
sme_set_md_host_evt_cb(mac_handle, hdd_md_host_evt_cb, (void *)hdd_ctx);
#endif /* WLAN_FEATURE_MOTION_DETECTION */
hdd_exit();
return ret;

View file

@ -1095,7 +1095,12 @@
*
* </ioctl>
*/
#define WE_SET_MODULATED_DTIM 96
#define WE_SET_MODULATED_DTIM 96
#ifdef WLAN_FEATURE_MOTION_DETECTION
#define WE_MOTION_DET_START_STOP 97
#define WE_MOTION_DET_BASE_LINE_START_STOP 98
#endif /* WLAN_FEATURE_MOTION_DETECTION */
/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_NONE_GET_INT (SIOCIWFIRSTPRIV + 1)
@ -2546,6 +2551,13 @@
#define MAX_VAR_ARGS 9
#endif
#ifdef WLAN_FEATURE_MOTION_DETECTION
#undef MAX_VAR_ARGS
#define MAX_VAR_ARGS 15
#define WE_MOTION_DET_CONFIG_PARAM 25
#define WE_MOTION_DET_BASE_LINE_CONFIG_PARAM 26
#endif /* WLAN_FEATURE_MOTION_DETECTION */
/*
* <ioctl>
* fips_test - Perform a FIPS test
@ -5157,6 +5169,61 @@ static int hdd_we_set_modulated_dtim(struct hdd_adapter *adapter, int value)
return 0;
}
#ifdef WLAN_FEATURE_MOTION_DETECTION
/**
* hdd_we_motion_det_start_stop - start/stop motion detection
* @adapter: hdd adapter
* @value: start/stop value to set
*
* Return: 0 on success, error on failure
*/
static int hdd_we_motion_det_start_stop(struct hdd_adapter *adapter, int value)
{
struct sme_motion_det_en motion_det;
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
if (value < 0 || value > 1) {
hdd_err("Invalid value %d in mt_start", value);
return -EINVAL;
}
motion_det.vdev_id = adapter->session_id;
motion_det.enable = value;
if (!value)
adapter->motion_detection_mode = 0;
sme_motion_det_enable(hdd_ctx->mac_handle, &motion_det);
return 0;
}
/**
* hdd_we_motion_det_base_line_start_stop - start/stop md baselining
* @adapter: hdd adapter
* @value: start/stop value to set
*
* Return: 0 on success, error on failure
*/
static int hdd_we_motion_det_base_line_start_stop(struct hdd_adapter *adapter,
int value)
{
struct sme_motion_det_base_line_en motion_det_base_line;
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
if (value < 0 || value > 1) {
hdd_err("Invalid value %d in mt_bl_start", value);
return -EINVAL;
}
motion_det_base_line.vdev_id = adapter->session_id;
motion_det_base_line.enable = value;
sme_motion_det_base_line_enable(hdd_ctx->mac_handle,
&motion_det_base_line);
return 0;
}
#endif /* WLAN_FEATURE_MOTION_DETECTION */
typedef int (*setint_getnone_fn)(struct hdd_adapter *adapter, int value);
static const setint_getnone_fn setint_getnone_cb[] = {
[WE_SET_11D_STATE] = hdd_we_set_11d_state,
@ -5252,6 +5319,11 @@ static const setint_getnone_fn setint_getnone_cb[] = {
[WE_SET_RANGE_EXT] = hdd_we_set_range_ext,
[WE_SET_PDEV_RESET] = hdd_handle_pdev_reset,
[WE_SET_MODULATED_DTIM] = hdd_we_set_modulated_dtim,
#ifdef WLAN_FEATURE_MOTION_DETECTION
[WE_MOTION_DET_START_STOP] = hdd_we_motion_det_start_stop,
[WE_MOTION_DET_BASE_LINE_START_STOP] =
hdd_we_motion_det_base_line_start_stop,
#endif /* WLAN_FEATURE_MOTION_DETECTION */
};
static setint_getnone_fn hdd_get_setint_getnone_cb(int param)
@ -7622,6 +7694,54 @@ static int __iw_set_var_ints_getnone(struct net_device *dev,
ret = cdp_txrx_stats_request(soc, vdev, &req);
break;
}
#ifdef WLAN_FEATURE_MOTION_DETECTION
case WE_MOTION_DET_CONFIG_PARAM:
{
struct sme_motion_det_cfg motion_det_cfg;
if (num_args != 15) {
hdd_err("mt_config: Invalid no of args");
return -EINVAL;
}
motion_det_cfg.vdev_id = adapter->session_id;
motion_det_cfg.time_t1 = apps_args[0];
motion_det_cfg.time_t2 = apps_args[1];
motion_det_cfg.n1 = apps_args[2];
motion_det_cfg.n2 = apps_args[3];
motion_det_cfg.time_t1_gap = apps_args[4];
motion_det_cfg.time_t2_gap = apps_args[5];
motion_det_cfg.coarse_K = apps_args[6];
motion_det_cfg.fine_K = apps_args[7];
motion_det_cfg.coarse_Q = apps_args[8];
motion_det_cfg.fine_Q = apps_args[9];
motion_det_cfg.md_coarse_thr_high = apps_args[10];
motion_det_cfg.md_fine_thr_high = apps_args[11];
motion_det_cfg.md_coarse_thr_low = apps_args[12];
motion_det_cfg.md_fine_thr_low = apps_args[13];
adapter->motion_detection_mode = apps_args[14];
sme_motion_det_config(hdd_ctx->mac_handle, &motion_det_cfg);
}
break;
case WE_MOTION_DET_BASE_LINE_CONFIG_PARAM:
{
struct sme_motion_det_base_line_cfg motion_det_base_line_cfg;
if (num_args != 4) {
hdd_err("mt_bl_config: Invalid no of args");
return -EINVAL;
}
motion_det_base_line_cfg.vdev_id = adapter->session_id;
motion_det_base_line_cfg.bl_time_t = apps_args[0];
motion_det_base_line_cfg.bl_packet_gap = apps_args[1];
motion_det_base_line_cfg.bl_n = apps_args[2];
motion_det_base_line_cfg.bl_num_meas = apps_args[3];
sme_motion_det_base_line_config(hdd_ctx->mac_handle,
&motion_det_base_line_cfg);
}
break;
#endif /* WLAN_FEATURE_MOTION_DETECTION */
default:
{
hdd_err("Invalid IOCTL command %d", sub_cmd);
@ -10510,11 +10630,33 @@ static const struct iw_priv_args we_private_args[] = {
0,
"range_ext"}
,
{WLAN_PRIV_SET_FTIES,
IW_PRIV_TYPE_CHAR | MAX_FTIE_SIZE,
0,
"set_ft_ies"},
"set_ft_ies"}
,
#ifdef WLAN_FEATURE_MOTION_DETECTION
{WE_MOTION_DET_START_STOP,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
0,
"mt_start"}
,
{WE_MOTION_DET_BASE_LINE_START_STOP,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
0,
"mt_bl_start"}
,
{WE_MOTION_DET_CONFIG_PARAM,
IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
0,
"mt_config"}
,
{WE_MOTION_DET_BASE_LINE_CONFIG_PARAM,
IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
0,
"mt_bl_config"}
,
#endif /* WLAN_FEATURE_MOTION_DETECTION */
};
const struct iw_handler_def we_handler_def = {

View file

@ -4955,8 +4955,10 @@ struct sir_wake_lock_stats {
* @gscan: gscan wakeup count
* @pno_complete: pno complete wakeup count
* @pno_match: pno match wakeup count
* @oem_response: oem response wakeup coun
* @oem_response: oem response wakeup count
* @scan_11d: 11d scan wakeup count
* @motion_detect: motion detection wakeup count
* @motion_detect_bl: motion detection baselining wakeup count
*/
struct sir_vdev_wow_stats {
uint32_t ucast;
@ -4976,6 +4978,10 @@ struct sir_vdev_wow_stats {
uint32_t oem_response;
uint32_t pwr_save_fail_detected;
uint32_t scan_11d;
#ifdef WLAN_FEATURE_MOTION_DETECTION
uint32_t motion_detect;
uint32_t motion_detect_bl;
#endif /* WLAN_FEATURE_MOTION_DETECTION */
};
#endif
@ -6128,4 +6134,15 @@ struct set_pcl_req {
enum band_info band;
};
/**
* struct sir_md_evt - motion detection event status
* @vdev_id: vdev id
* @status: md event status
*/
#ifdef WLAN_FEATURE_MOTION_DETECTION
struct sir_md_evt {
uint8_t vdev_id;
uint32_t status;
};
#endif /* WLAN_FEATURE_MOTION_DETECTION */
#endif /* __SIR_API_H */

View file

@ -648,8 +648,17 @@ struct sir_cfg_action_frm_tb_ppdu {
#define SIR_HAL_SEND_AP_VDEV_UP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 400)
#define SIR_HAL_SEND_BCN_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 401)
#define SIR_HAL_CFG_VENDOR_ACTION_TB_PPDU (SIR_HAL_ITC_MSG_TYPES_BEGIN + 402)
#define SIR_HAL_BEACON_DEBUG_STATS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 403)
#define SIR_HAL_BEACON_DEBUG_STATS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 403)
#define SIR_HAL_ROAM_BLACKLIST_MSG (SIR_HAL_ITC_MSG_TYPES_BEGIN + 404)
#ifdef WLAN_FEATURE_MOTION_DETECTION
#define SIR_HAL_SET_MOTION_DET_CONFIG (SIR_HAL_ITC_MSG_TYPES_BEGIN + 405)
#define SIR_HAL_SET_MOTION_DET_ENABLE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 406)
#define SIR_HAL_SET_MOTION_DET_BASE_LINE_CONFIG \
(SIR_HAL_ITC_MSG_TYPES_BEGIN + 407)
#define SIR_HAL_SET_MOTION_DET_BASE_LINE_ENABLE \
(SIR_HAL_ITC_MSG_TYPES_BEGIN + 408)
#endif /* WLAN_FEATURE_MOTION_DETECTION */
#define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
/* CFG message types */

View file

@ -3005,4 +3005,158 @@ void sme_update_score_config(mac_handle_t mac_handle,
* Return: None
*/
void sme_enable_fw_module_log_level(mac_handle_t mac_handle, int vdev_id);
#ifdef WLAN_FEATURE_MOTION_DETECTION
/**
* sme_motion_det_cfg - motion detection configuration
* @vdev_id: vdev id
* @time_t1: Time T1 for motion detection in msecs
* @time_t2: Time T2 for motion detection in msecs
* @n1: number of packets for coarse detection
* @n2: number of packets for fine detection
* @time_t1_gap: gap between packets in coarse detection in msecs
* @time_t2_gap: gap between packets in fine detection in msecs
* @coarse_k: number of times fine motion detection has to be performed for
* coarse detection
* @fine_k: number of times fine motion detection has to be performed for
* fine detection
* @coarse_q: number of times motion is expected to be detected for success
* case in coarse detection
* @fine_q: number of times motion is expected to be detected for success
* case in fine detection
* @md_coarse_thr_high: higher threshold value (in percent) from host to FW,
* which will be used in coarse detection phase of motion
* detection. This is the threshold for the correlation of
* the old RF local-scattering environment with current RF
* local-scattering environment. Value of 100(%) indicates
* that neither the transceiver nor any nearby objects
* have changed position
* @md_fine_thr_high: higher threshold value (in percent) from host to FW, which
* will be used in fine detection phase of motion detection.
* This is the threshold for correlation between the old and
* current RF environments, as explained above
* @md_coarse_thr_low: lower threshold value (in percent) for immediate
* detection of motion in coarse detection phase. This is
* the threshold for correlation between the old and current
* RF environments, as explained above
* @md_fine_thr_low: lower threshold value (in percent) for immediate detection
* of motion in fine detection phase. This is the threshold
* for correlation between the old and current RF
* environments, as explained above
* @eSME_TDLS_PEER_REMOVE_MAC_ADDR: remove peer mac from connection table
*/
struct sme_motion_det_cfg {
uint8_t vdev_id;
uint32_t time_t1;
uint32_t time_t2;
uint32_t n1;
uint32_t n2;
uint32_t time_t1_gap;
uint32_t time_t2_gap;
uint32_t coarse_K;
uint32_t fine_K;
uint32_t coarse_Q;
uint32_t fine_Q;
uint8_t md_coarse_thr_high;
uint8_t md_fine_thr_high;
uint8_t md_coarse_thr_low;
uint8_t md_fine_thr_low;
};
/**
* sme_motion_det_base_line_cfg - motion detection base line configuration
* @vdev_id : vdev id
* @bl_time_t: time T for baseline (in ms), every bl_time_t, bl_n pkts are sent
* @bl_packet_gap: gap between packets for baseline in msecs
* bl_n: number of packets to be sent during one baseline
* bl_num_meas: number of times the baseline measurement to be done
*/
struct sme_motion_det_base_line_cfg {
uint8_t vdev_id;
uint32_t bl_time_t;
uint32_t bl_packet_gap;
uint32_t bl_n;
uint32_t bl_num_meas;
};
/**
* sme_motion_det_en - Start/Stop motion detection
* @vdev_id: vdev_id
* @enable: start = 1, stop =0
*/
struct sme_motion_det_en {
uint8_t vdev_id;
bool enable;
};
/**
* sme_motion_det_base_line_en - Start/Stop motion detection base line
* @vdev_id: vdev_id
* @enable: start = 1, stop =0
*/
struct sme_motion_det_base_line_en {
uint8_t vdev_id;
bool enable;
};
/**
* sme_motion_det_config - Post motion detection configuration msg to scheduler
* @mac_handle: mac handle
* @motion_det_cfg: motion detection configuration
*
* Return: QDF_STATUS_SUCCESS or non-zero on failure
*/
QDF_STATUS sme_motion_det_config(mac_handle_t mac_handle,
struct sme_motion_det_cfg *motion_det_cfg);
/**
* sme_motion_det_enable - Post motion detection start/stop msg to scheduler
* @mac_handle: mac handle
* @motion_det_en: motion detection start/stop
*
* Return: QDF_STATUS_SUCCESS or non-zero on failure
*/
QDF_STATUS sme_motion_det_enable(mac_handle_t mac_handle,
struct sme_motion_det_en *motion_det_en);
/**
* sme_motion_det_base_line_config - Post md baselining cfg msg to scheduler
* @mac_handle: mac handle
* @motion_det_base_line_cfg: motion detection baselining configuration
*
* Return: QDF_STATUS_SUCCESS or non-zero on failure
*/
QDF_STATUS sme_motion_det_base_line_config(
mac_handle_t mac_handle,
struct sme_motion_det_base_line_cfg *motion_det_base_line_cfg);
/**
* sme_motion_det_base_line_enable - Post md baselining enable msg to scheduler
* @mac_handle: mac handle
* @motion_det_base_line_en: motion detection baselining start/stop
*
* Return: QDF_STATUS_SUCCESS or non-zero on failure
*/
QDF_STATUS sme_motion_det_base_line_enable(
mac_handle_t mac_handle,
struct sme_motion_det_base_line_en *motion_det_base_line_en);
/**
* sme_set_md_host_evt_cb - Register/set motion detection callback
* @mac_handle: mac handle
* @callback_fn: motion detection callback function pointer
* @hdd_ctx: hdd context
*
* Return: QDF_STATUS_SUCCESS or non-zero on failure
*/
QDF_STATUS sme_set_md_host_evt_cb
(
mac_handle_t mac_handle,
QDF_STATUS (*callback_fn)(void *ctx, struct sir_md_evt *event),
void *hdd_ctx
);
#endif /* WLAN_FEATURE_MOTION_DETECTION */
#endif /* #if !defined( __SME_API_H ) */

View file

@ -228,6 +228,10 @@ typedef void (*rso_cmd_status_cb)(hdd_handle_t hdd_handle,
typedef void (*lost_link_info_cb)(hdd_handle_t hdd_handle,
struct sir_lost_link_info *lost_link_info);
#ifdef WLAN_FEATURE_MOTION_DETECTION
typedef QDF_STATUS (*md_host_evt_cb)(void *hdd_ctx, sir_md_evt *event);
#endif /* WLAN_FEATURE_MOTION_DETECTION */
typedef struct tagSmeStruct {
eSmeState state;
qdf_mutex_t lkSmeGlobalLock;
@ -315,6 +319,10 @@ typedef struct tagSmeStruct {
apf_get_offload_cb apf_get_offload_cb;
apf_read_mem_cb apf_read_mem_cb;
#endif
#ifdef WLAN_FEATURE_MOTION_DETECTION
md_host_evt_cb md_host_evt_cb;
void *md_ctx;
#endif /* WLAN_FEATURE_MOTION_DETECTION */
} tSmeStruct, *tpSmeStruct;
#endif /* #if !defined( __SMEINTERNAL_H ) */

View file

@ -14919,3 +14919,206 @@ void sme_enable_fw_module_log_level(mac_handle_t mac_handle, int vdev_id)
count += 2;
}
}
#ifdef WLAN_FEATURE_MOTION_DETECTION
/**
* sme_set_md_host_evt_cb - Register/set motion detection callback
* @mac_handle: mac handle
* @callback_fn: motion detection callback function pointer
* @hdd_ctx: hdd context
*
* Return: QDF_STATUS_SUCCESS or non-zero on failure
*/
QDF_STATUS sme_set_md_host_evt_cb(
mac_handle_t mac_handle,
QDF_STATUS (*callback_fn)(void *ctx, struct sir_md_evt *event),
void *hdd_ctx
)
{
struct mac_context *mac = MAC_CONTEXT(mac_handle);
QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
qdf_status = sme_acquire_global_lock(&mac->sme);
if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
mac->sme.md_host_evt_cb = callback_fn;
mac->sme.md_ctx = hdd_ctx;
sme_release_global_lock(&mac->sme);
}
return qdf_status;
}
/**
* sme_motion_det_config - Post motion detection configuration msg to scheduler
* @mac_handle: mac handle
* @motion_det_config: motion detection configuration
*
* Return: QDF_STATUS_SUCCESS or non-zero on failure
*/
QDF_STATUS sme_motion_det_config(mac_handle_t mac_handle,
struct sme_motion_det_cfg *motion_det_config)
{
struct scheduler_msg msg = {0};
struct sme_motion_det_cfg *motion_det_cfg;
QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
struct mac_context *mac = MAC_CONTEXT(mac_handle);
qdf_status = sme_acquire_global_lock(&mac->sme);
if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
motion_det_cfg =
qdf_mem_malloc(sizeof(*motion_det_cfg));
if (!motion_det_cfg) {
sme_release_global_lock(&mac->sme);
return QDF_STATUS_E_NOMEM;
}
*motion_det_cfg = *motion_det_config;
qdf_mem_set(&msg, sizeof(msg), 0);
msg.type = WMA_SET_MOTION_DET_CONFIG;
msg.bodyptr = motion_det_cfg;
qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
QDF_MODULE_ID_WMA,
QDF_MODULE_ID_WMA,
&msg);
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
qdf_mem_free(motion_det_cfg);
qdf_status = QDF_STATUS_E_FAILURE;
}
sme_release_global_lock(&mac->sme);
}
return qdf_status;
}
/**
* sme_motion_det_enable - Post motion detection start/stop msg to scheduler
* @mac_handle: mac handle
* @motion_det_enable: motion detection start/stop
*
* Return: QDF_STATUS_SUCCESS or non-zero on failure
*/
QDF_STATUS sme_motion_det_enable(mac_handle_t mac_handle,
struct sme_motion_det_en *motion_det_enable)
{
struct scheduler_msg msg = {0};
struct sme_motion_det_en *motion_det_en;
QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
struct mac_context *mac = MAC_CONTEXT(mac_handle);
qdf_status = sme_acquire_global_lock(&mac->sme);
if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
motion_det_en = qdf_mem_malloc(sizeof(*motion_det_en));
if (!motion_det_en) {
sme_release_global_lock(&mac->sme);
return QDF_STATUS_E_NOMEM;
}
*motion_det_en = *motion_det_enable;
qdf_mem_set(&msg, sizeof(msg), 0);
msg.type = WMA_SET_MOTION_DET_ENABLE;
msg.bodyptr = motion_det_en;
qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
QDF_MODULE_ID_WMA,
QDF_MODULE_ID_WMA,
&msg);
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
qdf_mem_free(motion_det_en);
qdf_status = QDF_STATUS_E_FAILURE;
}
sme_release_global_lock(&mac->sme);
}
return qdf_status;
}
/**
* sme_motion_det_base_line_config - Post md baselining cfg msg to scheduler
* @mac_handle: mac handle
* @motion_det_base_line_config: motion detection baselining configuration
*
* Return: QDF_STATUS_SUCCESS or non-zero on failure
*/
QDF_STATUS sme_motion_det_base_line_config(
mac_handle_t mac_handle,
struct sme_motion_det_base_line_cfg *motion_det_base_line_config)
{
struct scheduler_msg msg = {0};
struct sme_motion_det_base_line_cfg *motion_det_base_line_cfg;
QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
struct mac_context *mac = MAC_CONTEXT(mac_handle);
qdf_status = sme_acquire_global_lock(&mac->sme);
if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
motion_det_base_line_cfg =
qdf_mem_malloc(sizeof(*motion_det_base_line_cfg));
if (!motion_det_base_line_cfg) {
sme_release_global_lock(&mac->sme);
return QDF_STATUS_E_NOMEM;
}
*motion_det_base_line_cfg = *motion_det_base_line_config;
qdf_mem_set(&msg, sizeof(msg), 0);
msg.type = WMA_SET_MOTION_DET_BASE_LINE_CONFIG;
msg.bodyptr = motion_det_base_line_cfg;
qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
QDF_MODULE_ID_WMA,
QDF_MODULE_ID_WMA,
&msg);
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
qdf_mem_free(motion_det_base_line_cfg);
qdf_status = QDF_STATUS_E_FAILURE;
}
sme_release_global_lock(&mac->sme);
}
return qdf_status;
}
/**
* sme_motion_det_base_line_enable - Post md baselining enable msg to scheduler
* @mac_handle: mac handle
* @motion_det_base_line_enable: motion detection baselining start/stop
*
* Return: QDF_STATUS_SUCCESS or non-zero on failure
*/
QDF_STATUS sme_motion_det_base_line_enable(
mac_handle_t mac_handle,
struct sme_motion_det_base_line_en *motion_det_base_line_enable)
{
struct scheduler_msg msg = {0};
struct sme_motion_det_base_line_en *motion_det_base_line_en;
QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
struct mac_context *mac = MAC_CONTEXT(mac_handle);
qdf_status = sme_acquire_global_lock(&mac->sme);
if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
motion_det_base_line_en =
qdf_mem_malloc(sizeof(*motion_det_base_line_en));
if (!motion_det_base_line_en) {
sme_release_global_lock(&mac->sme);
return QDF_STATUS_E_NOMEM;
}
*motion_det_base_line_en = *motion_det_base_line_enable;
qdf_mem_set(&msg, sizeof(msg), 0);
msg.type = WMA_SET_MOTION_DET_BASE_LINE_ENABLE;
msg.bodyptr = motion_det_base_line_en;
qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
QDF_MODULE_ID_WMA,
QDF_MODULE_ID_WMA,
&msg);
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
qdf_mem_free(motion_det_base_line_en);
qdf_status = QDF_STATUS_E_FAILURE;
}
sme_release_global_lock(&mac->sme);
}
return qdf_status;
}
#endif /* WLAN_FEATURE_MOTION_DETECTION */

View file

@ -2595,4 +2595,31 @@ void wma_update_set_key(uint8_t session_id, bool pairwise,
*/
uint8_t *wma_get_igtk(struct wma_txrx_node *iface, uint16_t *key_len);
#ifdef WLAN_FEATURE_MOTION_DETECTION
/**
* wma_motion_det_host_event_handler - motion detection event handler
* @handle: WMA global handle
* @event: motion detection event
* @len: Length of cmd
*
* Call motion detection event callback handler
*
* Return: 0 on success, else error on failure
*/
int wma_motion_det_host_event_handler(void *handle, u_int8_t *event,
u_int32_t len);
/**
* wma_motion_det_base_line_host_event_handler - md baselining event handler
* @handle: WMA global handle
* @event: motion detection baselining event
* @len: Length of cmd
*
* Return: 0 on success, else error on failure
*/
int wma_motion_det_base_line_host_event_handler(void *handle, u_int8_t *event,
u_int32_t len);
#endif /* WLAN_FEATURE_MOTION_DETECTION */
#endif

View file

@ -457,6 +457,15 @@
#define WMA_CFG_VENDOR_ACTION_TB_PPDU SIR_HAL_CFG_VENDOR_ACTION_TB_PPDU
#define WMA_GET_ROAM_SCAN_STATS SIR_HAL_GET_ROAM_SCAN_STATS
#ifdef WLAN_FEATURE_MOTION_DETECTION
#define WMA_SET_MOTION_DET_CONFIG SIR_HAL_SET_MOTION_DET_CONFIG
#define WMA_SET_MOTION_DET_ENABLE SIR_HAL_SET_MOTION_DET_ENABLE
#define WMA_SET_MOTION_DET_BASE_LINE_CONFIG \
SIR_HAL_SET_MOTION_DET_BASE_LINE_CONFIG
#define WMA_SET_MOTION_DET_BASE_LINE_ENABLE \
SIR_HAL_SET_MOTION_DET_BASE_LINE_ENABLE
#endif /* WLAN_FEATURE_MOTION_DETECTION */
/* Bit 6 will be used to control BD rate for Management frames */
#define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40

View file

@ -1570,6 +1570,12 @@ static const uint8_t *wma_wow_wake_reason_str(A_INT32 wake_reason)
return "SAP_OBSS_DETECTION";
case WOW_REASON_BSS_COLOR_COLLISION_DETECT:
return "BSS_COLOR_COLLISION_DETECT";
#ifdef WLAN_FEATURE_MOTION_DETECTION
case WOW_REASON_WLAN_MD:
return "MOTION_DETECT";
case WOW_REASON_WLAN_BL:
return "MOTION_DETECT_BASELINE";
#endif /* WLAN_FEATURE_MOTION_DETECTION */
default:
return "unknown";
}
@ -1600,6 +1606,11 @@ static bool wma_wow_reason_has_stats(enum wake_reason_e reason)
case WOW_REASON_CHIP_POWER_FAILURE_DETECT:
case WOW_REASON_11D_SCAN:
return true;
#ifdef WLAN_FEATURE_MOTION_DETECTION
case WOW_REASON_WLAN_MD:
case WOW_REASON_WLAN_BL:
return true;
#endif /* WLAN_FEATURE_MOTION_DETECTION */
default:
return false;
}
@ -1712,6 +1723,11 @@ static void wma_print_wow_stats(t_wma_handle *wma,
case WOW_REASON_CHIP_POWER_FAILURE_DETECT:
case WOW_REASON_11D_SCAN:
break;
#ifdef WLAN_FEATURE_MOTION_DETECTION
case WOW_REASON_WLAN_MD:
case WOW_REASON_WLAN_BL:
break;
#endif /* WLAN_FEATURE_MOTION_DETECTION */
default:
return;
}
@ -1768,6 +1784,14 @@ static void wma_inc_wow_stats(t_wma_handle *wma,
case WOW_REASON_CHIP_POWER_FAILURE_DETECT:
stats->pwr_save_fail_detected++;
break;
#ifdef WLAN_FEATURE_MOTION_DETECTION
case WOW_REASON_WLAN_MD::
stats->motion_detect++;
break;
case WOW_REASON_WLAN_BL:
stats->motion_detect_bl++;
break;
#endif /* WLAN_FEATURE_MOTION_DETECTION */
}
}
#endif

View file

@ -3083,6 +3083,42 @@ static void wma_register_apf_events(tp_wma_handle wma_handle)
}
#endif /* FEATURE_WLAN_APF */
#ifdef WLAN_FEATURE_MOTION_DETECTION
/**
* wma_register_md_events - Register motion detection event handlers
* @wma_handle: wma handle
* Return: None
*/
static void wma_register_md_events(tp_wma_handle wma_handle)
{
if (!wma_handle) {
QDF_TRACE(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_INFO,
"wma_handle is NULL\n");
return;
}
wmi_unified_register_event_handler(wma_handle->wmi_handle,
WMI_MOTION_DET_HOST_EVENTID,
wma_motion_det_host_event_handler,
WMA_RX_SERIALIZER_CTX);
wmi_unified_register_event_handler(
wma_handle->wmi_handle,
WMI_MOTION_DET_BASE_LINE_HOST_EVENTID,
wma_motion_det_base_line_host_event_handler,
WMA_RX_SERIALIZER_CTX);
}
#else /* WLAN_FEATURE_MOTION_DETECTION */
/**
* wma_register_md_events - Register motion detection event handlers
* @wma_handle: wma handle
* Return: None
*/
static void wma_register_md_events(tp_wma_handle wma_handle)
{
}
#endif /* WLAN_FEATURE_MOTION_DETECTION */
struct wlan_objmgr_psoc *wma_get_psoc_from_scn_handle(void *scn_handle)
{
tp_wma_handle wma_handle;
@ -3669,6 +3705,7 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc,
#endif
wma_register_apf_events(wma_handle);
wma_register_md_events(wma_handle);
return QDF_STATUS_SUCCESS;
@ -7949,6 +7986,300 @@ static void wma_send_obss_detection_cfg(tp_wma_handle wma_handle,
return;
}
#ifdef WLAN_FEATURE_MOTION_DETECTION
/**
* wma_motion_det_host_event_handler - motion detection event handler
* @handle: WMA global handle
* @event: motion detection event
* @len: Length of cmd
*
* Call motion detection event callback handler
*
* Return: 0 on success, else error on failure
*/
int wma_motion_det_host_event_handler(void *handle, uint8_t *event,
uint32_t len)
{
wmi_motion_det_event *motion_det_event_hdr;
WMI_MOTION_DET_HOST_EVENTID_param_tlvs *param_buf =
(WMI_MOTION_DET_HOST_EVENTID_param_tlvs *)event;
struct sir_md_evt *md_event;
struct mac_context *pmac = (struct mac_context *)cds_get_context(
QDF_MODULE_ID_PE);
if (!param_buf) {
WMA_LOGE("Invalid motion det host event buffer");
return -EINVAL;
}
motion_det_event_hdr = param_buf->fixed_param;
WMA_LOGA("motion detect host event received, vdev_id=%d, status=%d",
motion_det_event_hdr->vdev_id, motion_det_event_hdr->status);
md_event = qdf_mem_malloc(sizeof(*md_event));
if (!event)
return -ENOMEM;
md_event->vdev_id = motion_det_event_hdr->vdev_id;
md_event->status = motion_det_event_hdr->status;
pmac->sme.md_host_evt_cb(pmac->sme.md_ctx, md_event);
qdf_mem_free(md_event);
return 0;
}
/**
* wma_motion_det_base_line_host_event_handler - md baselining event handler
* @handle: WMA global handle
* @event: motion detection baselining event
* @len: Length of cmd
*
* Return: 0 on success, else error on failure
*/
int wma_motion_det_base_line_host_event_handler(void *handle,
uint8_t *event, uint32_t len)
{
wmi_motion_det_base_line_event *motion_det_base_line_event_hdr;
WMI_MOTION_DET_BASE_LINE_HOST_EVENTID_param_tlvs *param_buf =
(WMI_MOTION_DET_BASE_LINE_HOST_EVENTID_param_tlvs *)event;
if (!param_buf) {
WMA_LOGE("Invalid motion det base line event buffer");
return -EINVAL;
}
motion_det_base_line_event_hdr = param_buf->fixed_param;
WMA_LOGA("motion host detect base line event received, vdev_id=%d",
motion_det_base_line_event_hdr->vdev_id);
WMA_LOGA("baseline_value=%d bl_max_corr_resv=%d bl_min_corr_resv=%d",
motion_det_base_line_event_hdr->bl_baseline_value,
motion_det_base_line_event_hdr->bl_max_corr_reserved,
motion_det_base_line_event_hdr->bl_min_corr_reserved);
return 0;
}
/**
* wma_set_motion_det_config - Sends motion detection configuration wmi cmd
* @wma_handle: WMA global handle
* @motion_det_cfg: motion detection configuration
*
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_ERROR on error
*/
static QDF_STATUS wma_set_motion_det_config(
tp_wma_handle wma_handle,
struct sme_motion_det_cfg *motion_det_cfg)
{
wmi_motion_det_config_params_cmd_fixed_param *cmd;
wmi_buf_t buf;
int err;
buf = wmi_buf_alloc(wma_handle->wmi_handle, sizeof(*cmd));
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_motion_det_config_params_cmd_fixed_param *)wmi_buf_data(buf);
qdf_mem_zero(cmd, sizeof(*cmd));
WMITLV_SET_HDR(
&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_motion_det_config_params_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN(
wmi_motion_det_config_params_cmd_fixed_param));
cmd->vdev_id = motion_det_cfg->vdev_id;
cmd->time_t1 = motion_det_cfg->time_t1;
cmd->time_t2 = motion_det_cfg->time_t2;
cmd->n1 = motion_det_cfg->n1;
cmd->n2 = motion_det_cfg->n2;
cmd->time_t1_gap = motion_det_cfg->time_t1_gap;
cmd->time_t2_gap = motion_det_cfg->time_t2_gap;
cmd->coarse_K = motion_det_cfg->coarse_K;
cmd->fine_K = motion_det_cfg->fine_K;
cmd->coarse_Q = motion_det_cfg->coarse_Q;
cmd->fine_Q = motion_det_cfg->fine_Q;
cmd->md_coarse_thr_high = motion_det_cfg->md_coarse_thr_high;
cmd->md_fine_thr_high = motion_det_cfg->md_fine_thr_high;
cmd->md_coarse_thr_low = motion_det_cfg->md_coarse_thr_low;
cmd->md_fine_thr_low = motion_det_cfg->md_fine_thr_low;
err = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, sizeof(*cmd),
WMI_MOTION_DET_CONFIG_PARAM_CMDID);
if (err) {
wmi_buf_free(buf);
return QDF_STATUS_E_FAILURE;
}
WMA_LOGA("Set motion_det_config to vdevId %d\n"
"time_t1 %d\n"
"time_t2 %d\n"
"n1 %d\n"
"n2 %d\n"
"time_t1_gap %d\n"
"time_t2_gap %d\n"
"coarse_K %d\n"
"fine_K %d\n"
"coarse_Q %d\n"
"fine_Q %d\n"
"md_coarse_thr_high %d\n"
"md_fine_thr_high %d\n"
"md_coarse_thr_low %d\n"
"md_fine_thr_low %d\n",
motion_det_cfg->vdev_id,
motion_det_cfg->time_t1,
motion_det_cfg->time_t2,
motion_det_cfg->n1,
motion_det_cfg->n2,
motion_det_cfg->time_t1_gap,
motion_det_cfg->time_t2_gap,
motion_det_cfg->coarse_K,
motion_det_cfg->fine_K,
motion_det_cfg->coarse_Q,
motion_det_cfg->fine_Q,
motion_det_cfg->md_coarse_thr_high,
motion_det_cfg->md_fine_thr_high,
motion_det_cfg->md_coarse_thr_low,
motion_det_cfg->md_fine_thr_low);
return QDF_STATUS_SUCCESS;
}
/**
* wma_set_motion_det_enable - Sends motion detection start/stop wmi cmd
* @wma_handle: WMA global handle
* @md_en: motion detection start/stop
*
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_ERROR on error
*/
static QDF_STATUS wma_set_motion_det_enable(tp_wma_handle wma_handle,
struct sme_motion_det_en *md_en)
{
wmi_motion_det_start_stop_cmd_fixed_param *cmd;
wmi_buf_t buf;
int err;
buf = wmi_buf_alloc(wma_handle->wmi_handle, sizeof(*cmd));
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_motion_det_start_stop_cmd_fixed_param *)wmi_buf_data(buf);
qdf_mem_zero(cmd, sizeof(*cmd));
WMITLV_SET_HDR(
&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_motion_det_start_stop_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN(
wmi_motion_det_start_stop_cmd_fixed_param));
cmd->vdev_id = md_en->vdev_id;
cmd->enable = md_en->enable;
err = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, sizeof(*cmd),
WMI_MOTION_DET_START_STOP_CMDID);
if (err) {
wmi_buf_free(buf);
return QDF_STATUS_E_FAILURE;
}
WMA_LOGA("Set motion_det_enable to vdevId %d %d", md_en->vdev_id,
md_en->enable);
return QDF_STATUS_SUCCESS;
}
/**
* wma_set_motion_det_base_line_config - Sends md baselining cfg wmi cmd
* @wma_handle: WMA global handle
* @md_base_line_cfg: md baselining configuration
*
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_ERROR on error
*/
static QDF_STATUS wma_set_motion_det_base_line_config(
tp_wma_handle wma_handle,
struct sme_motion_det_base_line_cfg *md_base_line_cfg)
{
wmi_motion_det_base_line_config_params_cmd_fixed_param *cmd;
wmi_buf_t buf;
int err;
buf = wmi_buf_alloc(wma_handle->wmi_handle, sizeof(*cmd));
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_motion_det_base_line_config_params_cmd_fixed_param *)
wmi_buf_data(buf);
qdf_mem_zero(cmd, sizeof(*cmd));
WMITLV_SET_HDR(
&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_motion_det_base_line_config_params_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN(
wmi_motion_det_base_line_config_params_cmd_fixed_param));
cmd->vdev_id = md_base_line_cfg->vdev_id;
cmd->bl_time_t = md_base_line_cfg->bl_time_t;
cmd->bl_packet_gap = md_base_line_cfg->bl_packet_gap;
cmd->bl_n = md_base_line_cfg->bl_n;
cmd->bl_num_meas = md_base_line_cfg->bl_num_meas;
err = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, sizeof(*cmd),
WMI_MOTION_DET_BASE_LINE_CONFIG_PARAM_CMDID);
if (err) {
wmi_buf_free(buf);
return QDF_STATUS_E_FAILURE;
}
WMA_LOGA("Set motion_det_baseline_config to vdevId %d\n"
"bl_time_t %d\n"
"bl_packet_gap %d\n"
"bl_n %d\n"
"bl_num_meas %d\n",
md_base_line_cfg->vdev_id,
md_base_line_cfg->bl_time_t,
md_base_line_cfg->bl_packet_gap,
md_base_line_cfg->bl_n,
md_base_line_cfg->bl_num_meas);
return QDF_STATUS_SUCCESS;
}
/**
* wma_set_motion_det_base_line_enable - Sends md baselining start/stop wmi cmd
* @wma_handle: WMA global handle
* @md_base_line_en: motion detection baselining start/stop
*
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_ERROR on error
*/
static QDF_STATUS wma_set_motion_det_base_line_enable(
tp_wma_handle wma_handle,
struct sme_motion_det_base_line_en *md_base_line_en)
{
wmi_motion_det_base_line_start_stop_cmd_fixed_param *cmd;
wmi_buf_t buf;
int err;
buf = wmi_buf_alloc(wma_handle->wmi_handle, sizeof(*cmd));
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_motion_det_base_line_start_stop_cmd_fixed_param *)
wmi_buf_data(buf);
qdf_mem_zero(cmd, sizeof(*cmd));
WMITLV_SET_HDR(
cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_motion_det_base_line_start_stop_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN(
wmi_motion_det_base_line_start_stop_cmd_fixed_param));
cmd->vdev_id = md_base_line_en->vdev_id;
cmd->enable = md_base_line_en->enable;
err = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, sizeof(*cmd),
WMI_MOTION_DET_BASE_LINE_START_STOP_CMDID);
if (err) {
wmi_buf_free(buf);
return QDF_STATUS_E_FAILURE;
}
WMA_LOGA("Set motion_det_base_line_enable to vdevId %d enable %d",
md_base_line_en->vdev_id, md_base_line_en->enable);
return QDF_STATUS_SUCCESS;
}
#endif /* WLAN_FEATURE_MOTION_DETECTION */
/**
* wma_mc_process_msg() - process wma messages and call appropriate function.
* @msg: message
@ -8654,6 +8985,32 @@ static QDF_STATUS wma_mc_process_msg(struct scheduler_msg *msg)
wma_get_roam_scan_stats(wma_handle, msg->bodyptr);
qdf_mem_free(msg->bodyptr);
break;
#ifdef WLAN_FEATURE_MOTION_DETECTION
case WMA_SET_MOTION_DET_CONFIG:
wma_set_motion_det_config(
wma_handle,
(struct sme_motion_det_cfg *)msg->bodyptr);
qdf_mem_free(msg->bodyptr);
break;
case WMA_SET_MOTION_DET_ENABLE:
wma_set_motion_det_enable(
wma_handle,
(struct sme_motion_det_en *)msg->bodyptr);
qdf_mem_free(msg->bodyptr);
break;
case WMA_SET_MOTION_DET_BASE_LINE_CONFIG:
wma_set_motion_det_base_line_config(
wma_handle,
(struct sme_motion_det_base_line_cfg *)msg->bodyptr);
qdf_mem_free(msg->bodyptr);
break;
case WMA_SET_MOTION_DET_BASE_LINE_ENABLE:
wma_set_motion_det_base_line_enable(
wma_handle,
(struct sme_motion_det_base_line_en *)msg->bodyptr);
qdf_mem_free(msg->bodyptr);
break;
#endif /* WLAN_FEATURE_MOTION_DETECTION */
default:
WMA_LOGD("Unhandled WMA message of type %d", msg->type);
if (msg->bodyptr)