Browse Source

qcacld-3.0: Add a sysfs replacement for motion detection commands

As part of WEXT replacement, replace mt_bl_config, mt_bl_start,
mt_config, mt_start with a sysfs file.

file path: /sys/class/net/wlanxx/mt_bl_config
file path: /sys/class/net/wlanxx/mt_bl_start
file path: /sys/class/net/wlanxx/mt_config
file path: /sys/class/net/wlanxx/mt_start
        wlanxx is adapter name

example: echo 1 1 1 1 > mt_bl_config
example: echo 1 > mt_bl_start
example: echo 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 > mt_config
example: echo 1 > mt_start

Change-Id: Ife5df2cfae7c9489d6e9d6c2746a1e7367ed5012
CRs-Fixed: 2686772
Alan Chen 4 years ago
parent
commit
b04e0e3c61

+ 3 - 0
Kbuild

@@ -324,6 +324,9 @@ endif
 ifeq ($(CONFIG_WLAN_THERMAL_CFG), y)
 HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_thermal_cfg.o
 endif
+ifeq ($(CONFIG_FEATURE_MOTION_DETECTION), y)
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs_motion_detection.o
+endif
 endif
 
 ifeq ($(CONFIG_QCACLD_FEATURE_FW_STATE), y)

+ 3 - 0
core/hdd/src/wlan_hdd_sysfs.c

@@ -60,6 +60,7 @@
 #include <wlan_hdd_sysfs_get_tdls_peers.h>
 #include <wlan_hdd_sysfs_get_temp.h>
 #include <wlan_hdd_sysfs_thermal_cfg.h>
+#include <wlan_hdd_sysfs_motion_detection.h>
 
 #define MAX_PSOC_ID_SIZE 10
 
@@ -645,11 +646,13 @@ hdd_sysfs_create_sta_adapter_root_obj(struct hdd_adapter *adapter)
 	hdd_sysfs_get_range_ext_create(adapter);
 	hdd_sysfs_get_tdls_peers_interface_create(adapter);
 	hdd_sysfs_get_temp_create(adapter);
+	hdd_sysfs_motion_detection_create(adapter);
 }
 
 static void
 hdd_sysfs_destroy_sta_adapter_root_obj(struct hdd_adapter *adapter)
 {
+	hdd_sysfs_motion_detection_destroy(adapter);
 	hdd_sysfs_get_temp_destroy(adapter);
 	hdd_sysfs_get_tdls_peers_interface_destroy(adapter);
 	hdd_sysfs_get_range_ext_destroy(adapter);

+ 502 - 0
core/hdd/src/wlan_hdd_sysfs_motion_detection.c

@@ -0,0 +1,502 @@
+/*
+ * Copyright (c) 2011-2020 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: wlan_hdd_sysfs_motion_detection.c
+ *
+ * implementation for creating sysfs file motion_detection
+ */
+
+#include <wlan_hdd_includes.h>
+#include <wlan_hdd_main.h>
+#include "osif_vdev_sync.h"
+#include <wlan_hdd_sysfs.h>
+#include <wlan_hdd_sysfs_motion_detection.h>
+#include "sme_api.h"
+
+#define HDD_SYSFS_MT_CONFIG_UINT32_ARGS (10)
+#define HDD_SYSFS_MT_CONFIG_UINT8_ARGS (5)
+#define HDD_SYSFS_MT_CONFIG_NUM_ARGS (15)
+#define HDD_SYSFS_MT_CONFIG_UINT8_INDEX (11)
+#define MAX_SYSFS_MT_USER_COMMAND_SIZE_LENGTH (64)
+
+static ssize_t
+__hdd_sysfs_mt_bl_config_store(struct net_device *net_dev,
+			       char const *buf, size_t count)
+{
+	struct sme_motion_det_base_line_cfg motion_det_base_line_cfg;
+	struct hdd_adapter *adapter = netdev_priv(net_dev);
+	char buf_local[MAX_SYSFS_USER_COMMAND_SIZE_LENGTH + 1];
+	struct hdd_context *hdd_ctx;
+	char *sptr, *token;
+	uint32_t bl_time_t, bl_packet_gap, bl_n, bl_num_meas;
+	int ret;
+
+	if (hdd_validate_adapter(adapter)) {
+		hdd_err_rl("adapter validate fail");
+		return -EINVAL;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret != 0)
+		return ret;
+
+	if (!wlan_hdd_validate_modules_state(hdd_ctx))
+		return -EINVAL;
+
+	ret = hdd_sysfs_validate_and_copy_buf(buf_local, sizeof(buf_local),
+					      buf, count);
+
+	if (ret) {
+		hdd_err_rl("invalid input");
+		return ret;
+	}
+
+	sptr = buf_local;
+	hdd_debug("mt_bl_config: count %zu buf_local:(%s) net_devname %s",
+		  count, buf_local, net_dev->name);
+
+	/* Get val1 */
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &bl_time_t))
+		return -EINVAL;
+
+	/* Get val2 */
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &bl_packet_gap))
+		return -EINVAL;
+
+	/* Get val3 */
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &bl_n))
+		return -EINVAL;
+
+	/* Get val4 */
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &bl_num_meas))
+		return -EINVAL;
+
+	motion_det_base_line_cfg.vdev_id = adapter->vdev_id;
+	motion_det_base_line_cfg.bl_time_t = bl_time_t;
+	motion_det_base_line_cfg.bl_packet_gap = bl_packet_gap;
+	motion_det_base_line_cfg.bl_n = bl_n;
+	motion_det_base_line_cfg.bl_num_meas = bl_num_meas;
+	sme_motion_det_base_line_config(hdd_ctx->mac_handle,
+					&motion_det_base_line_cfg);
+
+	return count;
+}
+
+static ssize_t
+hdd_sysfs_mt_bl_config_store(struct device *dev,
+			     struct device_attribute *attr,
+			     char const *buf, size_t count)
+{
+	struct net_device *net_dev = container_of(dev, struct net_device, dev);
+	struct osif_vdev_sync *vdev_sync;
+	ssize_t errno_size;
+
+	errno_size = osif_vdev_sync_op_start(net_dev, &vdev_sync);
+	if (errno_size)
+		return errno_size;
+
+	errno_size = __hdd_sysfs_mt_bl_config_store(net_dev, buf, count);
+
+	osif_vdev_sync_op_stop(vdev_sync);
+
+	return errno_size;
+}
+
+static ssize_t
+__hdd_sysfs_mt_bl_start_store(struct net_device *net_dev,
+			      char const *buf, size_t count)
+{
+	struct sme_motion_det_base_line_en motion_det_base_line;
+	struct hdd_adapter *adapter = netdev_priv(net_dev);
+	char buf_local[MAX_SYSFS_USER_COMMAND_SIZE_LENGTH + 1];
+	struct hdd_context *hdd_ctx;
+	char *sptr, *token;
+	uint32_t value;
+	QDF_STATUS status;
+	int ret;
+
+	if (hdd_validate_adapter(adapter)) {
+		hdd_err_rl("adapter validate fail");
+		return -EINVAL;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret != 0)
+		return ret;
+
+	if (!wlan_hdd_validate_modules_state(hdd_ctx))
+		return -EINVAL;
+
+	ret = hdd_sysfs_validate_and_copy_buf(buf_local, sizeof(buf_local),
+					      buf, count);
+
+	if (ret) {
+		hdd_err_rl("invalid input");
+		return ret;
+	}
+
+	/* Do not send baselining start/stop during motion detection phase */
+	if (adapter->motion_det_in_progress) {
+		hdd_err("Motion detection still in progress, try later");
+		return -EAGAIN;
+	}
+
+	sptr = buf_local;
+	hdd_debug("mt_bl_start: count %zu buf_local:(%s) net_devname %s",
+		  count, buf_local, net_dev->name);
+
+	/* Get value */
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &value))
+		return -EINVAL;
+
+	if (value < 0 || value > 1) {
+		hdd_err("Invalid value %d in mt_bl_start", value);
+		return -EINVAL;
+	}
+
+	motion_det_base_line.vdev_id = adapter->vdev_id;
+	motion_det_base_line.enable = value;
+	status = sme_motion_det_base_line_enable(hdd_ctx->mac_handle,
+						 &motion_det_base_line);
+
+	if (status != QDF_STATUS_SUCCESS)
+		hdd_err("can't enable md baselining msg to scheduler");
+
+	return count;
+}
+
+static ssize_t
+hdd_sysfs_mt_bl_start_store(struct device *dev,
+			    struct device_attribute *attr,
+			    char const *buf, size_t count)
+{
+	struct net_device *net_dev = container_of(dev, struct net_device, dev);
+	struct osif_vdev_sync *vdev_sync;
+	ssize_t errno_size;
+
+	errno_size = osif_vdev_sync_op_start(net_dev, &vdev_sync);
+	if (errno_size)
+		return errno_size;
+
+	errno_size = __hdd_sysfs_mt_bl_start_store(net_dev, buf, count);
+
+	osif_vdev_sync_op_stop(vdev_sync);
+
+	return errno_size;
+}
+
+static ssize_t
+__hdd_sysfs_mt_config_store(struct net_device *net_dev,
+			    char const *buf, size_t count)
+{
+	struct sme_motion_det_cfg motion_det_cfg;
+	struct hdd_adapter *adapter = netdev_priv(net_dev);
+	char buf_local[MAX_SYSFS_MT_USER_COMMAND_SIZE_LENGTH + 1];
+	struct hdd_context *hdd_ctx;
+	char *sptr, *token;
+	uint8_t val_8[HDD_SYSFS_MT_CONFIG_UINT8_ARGS];
+	uint32_t val_32[HDD_SYSFS_MT_CONFIG_UINT32_ARGS];
+	int i, ret;
+
+	if (hdd_validate_adapter(adapter)) {
+		hdd_err_rl("adapter validate fail");
+		return -EINVAL;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret != 0)
+		return ret;
+
+	if (!wlan_hdd_validate_modules_state(hdd_ctx))
+		return -EINVAL;
+
+	ret = hdd_sysfs_validate_and_copy_buf(buf_local, sizeof(buf_local),
+					      buf, count);
+
+	if (ret) {
+		hdd_err_rl("invalid input");
+		return ret;
+	}
+
+	sptr = buf_local;
+	hdd_debug("mt_config: count %zu buf_local:(%s) net_devname %s",
+		  count, buf_local, net_dev->name);
+
+	for (i = 0; i < HDD_SYSFS_MT_CONFIG_NUM_ARGS; i++) {
+		token = strsep(&sptr, " ");
+		if (!token) {
+			hdd_err_rl("mt_config: not enough args(%d), expected args_num: 15",
+				   i);
+			return -EINVAL;
+		}
+		if ( i >= HDD_SYSFS_MT_CONFIG_UINT8_INDEX) {
+			if (kstrtou8(token, 0,
+				     &val_8[i - HDD_SYSFS_MT_CONFIG_UINT8_INDEX]))
+				return -EINVAL;
+		} else {
+			if (kstrtou32(token, 0, &val_32[i]))
+				return -EINVAL;
+		}
+	}
+
+	motion_det_cfg.vdev_id = adapter->vdev_id;
+	motion_det_cfg.time_t1 = val_32[0];
+	motion_det_cfg.time_t2 = val_32[1];
+	motion_det_cfg.n1 = val_32[2];
+	motion_det_cfg.n2 = val_32[3];
+	motion_det_cfg.time_t1_gap = val_32[4];
+	motion_det_cfg.time_t2_gap = val_32[5];
+	motion_det_cfg.coarse_K = val_32[6];
+	motion_det_cfg.fine_K = val_32[7];
+	motion_det_cfg.coarse_Q = val_32[8];
+	motion_det_cfg.fine_Q = val_32[9];
+	motion_det_cfg.md_coarse_thr_high = val_8[0];
+	motion_det_cfg.md_fine_thr_high = val_8[1];
+	motion_det_cfg.md_coarse_thr_low = val_8[2];
+	motion_det_cfg.md_fine_thr_low = val_8[3];
+	adapter->motion_detection_mode = val_8[4];
+	sme_motion_det_config(hdd_ctx->mac_handle, &motion_det_cfg);
+	adapter->motion_det_cfg =  true;
+
+	return count;
+}
+
+static ssize_t
+hdd_sysfs_mt_config_store(struct device *dev,
+			  struct device_attribute *attr,
+			  char const *buf, size_t count)
+{
+	struct net_device *net_dev = container_of(dev, struct net_device, dev);
+	struct osif_vdev_sync *vdev_sync;
+	ssize_t errno_size;
+
+	errno_size = osif_vdev_sync_op_start(net_dev, &vdev_sync);
+	if (errno_size)
+		return errno_size;
+
+	errno_size = __hdd_sysfs_mt_config_store(net_dev, buf, count);
+
+	osif_vdev_sync_op_stop(vdev_sync);
+
+	return errno_size;
+}
+
+static ssize_t
+__hdd_sysfs_mt_start_store(struct net_device *net_dev,
+			   char const *buf, size_t count)
+{
+	struct sme_motion_det_en motion_det;
+	struct hdd_adapter *adapter = netdev_priv(net_dev);
+	char buf_local[MAX_SYSFS_USER_COMMAND_SIZE_LENGTH + 1];
+	struct hdd_context *hdd_ctx;
+	char *sptr, *token;
+	uint32_t value;
+	int ret;
+
+	if (hdd_validate_adapter(adapter)) {
+		hdd_err_rl("adapter validate fail");
+		return -EINVAL;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret != 0)
+		return ret;
+
+	if (!wlan_hdd_validate_modules_state(hdd_ctx))
+		return -EINVAL;
+
+	ret = hdd_sysfs_validate_and_copy_buf(buf_local, sizeof(buf_local),
+					      buf, count);
+
+	if (ret) {
+		hdd_err_rl("invalid input");
+		return ret;
+	}
+
+	sptr = buf_local;
+	hdd_debug("mt_start: count %zu buf_local:(%s) net_devname %s",
+		  count, buf_local, net_dev->name);
+
+	/* Get value */
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &value))
+		return -EINVAL;
+
+	if (value < 0 || value > 1) {
+		hdd_err("Invalid value %d in mt_start", value);
+		return -EINVAL;
+	}
+
+	if (!adapter->motion_det_cfg) {
+		hdd_err("Motion Detection config values not availbale");
+		return -EINVAL;
+	}
+
+	if (!adapter->motion_det_baseline_value) {
+		hdd_err("Motion Detection Baselining not started/completed");
+		return -EAGAIN;
+	}
+
+	motion_det.vdev_id = adapter->vdev_id;
+	motion_det.enable = value;
+
+	if (value) {
+		/* For motion detection start, set motion_det_in_progress */
+		adapter->motion_det_in_progress = true;
+	} else {
+		/* For motion detection stop, reset motion_det_in_progress */
+		adapter->motion_det_in_progress = false;
+		adapter->motion_detection_mode = 0;
+	}
+
+	sme_motion_det_enable(hdd_ctx->mac_handle, &motion_det);
+
+	return count;
+}
+
+static ssize_t
+hdd_sysfs_mt_start_store(struct device *dev,
+			 struct device_attribute *attr,
+			 char const *buf, size_t count)
+{
+	struct net_device *net_dev = container_of(dev, struct net_device, dev);
+	struct osif_vdev_sync *vdev_sync;
+	ssize_t errno_size;
+
+	errno_size = osif_vdev_sync_op_start(net_dev, &vdev_sync);
+	if (errno_size)
+		return errno_size;
+
+	errno_size = __hdd_sysfs_mt_start_store(net_dev, buf, count);
+
+	osif_vdev_sync_op_stop(vdev_sync);
+
+	return errno_size;
+}
+
+static DEVICE_ATTR(mt_bl_config, 0220,
+		   NULL, hdd_sysfs_mt_bl_config_store);
+
+static DEVICE_ATTR(mt_bl_start, 0220,
+		   NULL, hdd_sysfs_mt_bl_start_store);
+
+static DEVICE_ATTR(mt_config, 0220,
+		   NULL, hdd_sysfs_mt_config_store);
+
+static DEVICE_ATTR(mt_start, 0220,
+		   NULL, hdd_sysfs_mt_start_store);
+
+static int hdd_sysfs_mt_bl_config_create(struct hdd_adapter *adapter)
+{
+	int error;
+
+	error = device_create_file(&adapter->dev->dev, &dev_attr_mt_bl_config);
+	if (error)
+		hdd_err("could not create mt_bl_config sysfs file");
+
+	return error;
+}
+
+static void hdd_sysfs_mt_bl_config_destroy(struct hdd_adapter *adapter)
+{
+	device_remove_file(&adapter->dev->dev, &dev_attr_mt_bl_config);
+}
+
+static int hdd_sysfs_mt_bl_start_create(struct hdd_adapter *adapter)
+{
+	int error;
+
+	error = device_create_file(&adapter->dev->dev, &dev_attr_mt_bl_start);
+	if (error)
+		hdd_err("could not create mt_bl_start sysfs file");
+
+	return error;
+}
+
+static void hdd_sysfs_mt_bl_start_destroy(struct hdd_adapter *adapter)
+{
+	device_remove_file(&adapter->dev->dev, &dev_attr_mt_bl_start);
+}
+
+static int hdd_sysfs_mt_config_create(struct hdd_adapter *adapter)
+{
+	int error;
+
+	error = device_create_file(&adapter->dev->dev, &dev_attr_mt_config);
+	if (error)
+		hdd_err("could not create mt_config sysfs file");
+
+	return error;
+}
+
+static void hdd_sysfs_mt_config_destroy(struct hdd_adapter *adapter)
+{
+	device_remove_file(&adapter->dev->dev, &dev_attr_mt_config);
+}
+
+static int hdd_sysfs_mt_start_create(struct hdd_adapter *adapter)
+{
+	int error;
+
+	error = device_create_file(&adapter->dev->dev, &dev_attr_mt_start);
+	if (error)
+		hdd_err("could not create mt_start sysfs file");
+
+	return error;
+}
+
+static void hdd_sysfs_mt_start_destroy(struct hdd_adapter *adapter)
+{
+	device_remove_file(&adapter->dev->dev, &dev_attr_mt_start);
+}
+
+void hdd_sysfs_motion_detection_create(struct hdd_adapter *adapter)
+{
+	hdd_sysfs_mt_bl_config_create(adapter);
+	hdd_sysfs_mt_bl_start_create(adapter);
+	hdd_sysfs_mt_config_create(adapter);
+	hdd_sysfs_mt_start_create(adapter);
+}
+
+void hdd_sysfs_motion_detection_destroy(struct hdd_adapter *adapter)
+{
+	hdd_sysfs_mt_start_destroy(adapter);
+	hdd_sysfs_mt_config_destroy(adapter);
+	hdd_sysfs_mt_bl_start_destroy(adapter);
+	hdd_sysfs_mt_bl_config_destroy(adapter);
+}

+ 87 - 0
core/hdd/src/wlan_hdd_sysfs_motion_detection.h

@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2011-2020 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: wlan_hdd_sysfs_motion_detection.h
+ *
+ * implementation for creating sysfs file motion_detection
+ */
+
+#ifndef _WLAN_HDD_SYSFS_MOTION_DETECTION_H
+#define _WLAN_HDD_SYSFS_MOTION_DETECTION_H
+
+#if defined(WLAN_SYSFS) && defined(WLAN_FEATURE_MOTION_DETECTION)
+/**
+ * wlan_hdd_sysfs_motion_detection_create() - API to create motion
+ * detection sysfs attributes
+ * @adapter: hdd adapter
+ *
+ * This API creates the following sysfs attributes:
+ * 1. mt_bl_config
+ * 2. mt_bl_start
+ * 3. mt_config
+ * 4. mt_start
+ *
+ * mt_bl_config: this file is created per adapter.
+ * file path: /sys/class/net/wlanxx/mt_bl_config
+ *                (wlanxx is adapter name)
+ * usage:
+ *      echo [arg_0] [arg_1] [arg_2] [arg_3] > mt_bl_config
+ *
+ * mt_bl_start: this file is created per adapter.
+ * file path: /sys/class/net/wlanxx/mt_bl_start
+ *                (wlanxx is adapter name)
+ * usage:
+ *      echo [arg_0] > mt_bl_start
+ *
+ * mt_config: this file is created per adapter.
+ * file path: /sys/class/net/wlanxx/mt_config
+ *                (wlanxx is adapter name)
+ * usage:
+ *      echo [arg_0] [arg_1] [arg_2] [arg_4] [arg_5] [arg_6] [arg_7] [arg_8]
+ *      [arg_9] [arg_10] [arg_11] [arg_12] [arg_13] [arg_14] > mt_config
+ *
+ * mt_start: this file is created per adapter.
+ * file path: /sys/class/net/wlanxx/mt_start
+ *                (wlanxx is adapter name)
+ * usage:
+ *      echo [arg_0] > mt_start
+ *
+ * Return: None
+ */
+void hdd_sysfs_motion_detection_create(struct hdd_adapter *adapter);
+
+/**
+ * hdd_sysfs_motion_detection_destroy() -
+ *   API to destroy motion detection sysfs attributes
+ * @adapter: pointer to adapter
+ *
+ * Return: none
+ */
+void hdd_sysfs_motion_detection_destroy(struct hdd_adapter *adapter);
+
+#else
+static inline void
+hdd_sysfs_motion_detection_create(struct hdd_adapter *adapter)
+{
+}
+
+static inline void
+hdd_sysfs_motion_detection_destroy(struct hdd_adapter *adapter)
+{
+}
+#endif
+#endif /* #ifndef _WLAN_HDD_SYSFS_MOTION_DETECTION_H */