Browse Source

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
Visweswara Tanuku 6 years ago
parent
commit
633976b5b0

+ 20 - 0
core/hdd/inc/wlan_hdd_main.h

@@ -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) */

+ 51 - 0
core/hdd/src/wlan_hdd_main.c

@@ -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;

+ 145 - 3
core/hdd/src/wlan_hdd_wext.c

@@ -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 = {

+ 18 - 1
core/mac/inc/sir_api.h

@@ -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 */

+ 10 - 1
core/mac/src/include/sir_params.h

@@ -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 */

+ 154 - 0
core/sme/inc/sme_api.h

@@ -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 ) */

+ 8 - 0
core/sme/inc/sme_internal.h

@@ -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 ) */

+ 203 - 0
core/sme/src/common/sme_api.c

@@ -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 */

+ 27 - 0
core/wma/inc/wma.h

@@ -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

+ 9 - 0
core/wma/inc/wma_types.h

@@ -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
 

+ 24 - 0
core/wma/src/wma_features.c

@@ -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

+ 357 - 0
core/wma/src/wma_main.c

@@ -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)