Bladeren bron

qcacld-3.0: Cache feature set file name and oem data info

Based on new requirement, cache feature set file name and
oem data info.

Change-Id: I01da429c856a99581558a1f81b43a1e7102a7846
CRs-Fixed: 3262817
Ashish Kumar Dhanotiya 2 jaren geleden
bovenliggende
commit
bfcf3d08f6

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

@@ -2019,6 +2019,11 @@ struct hdd_context {
 	uint8_t power_type;
 #endif
 	bool is_wlan_disabled;
+
+	uint8_t *oem_data;
+	uint8_t oem_data_len;
+	uint8_t *file_name;
+	qdf_mutex_t wifi_kobj_lock;
 };
 
 /**

+ 26 - 0
core/hdd/inc/wlan_hdd_sysfs.h

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2017-2018, 2020 The Linux Foundation. All rights reserved.
+* Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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
@@ -67,6 +68,23 @@ void hdd_create_adapter_sysfs_files(struct hdd_adapter *adapter);
  * Return: none
  */
 void hdd_destroy_adapter_sysfs_files(struct hdd_adapter *adapter);
+
+/**
+ * hdd_create_wifi_feature_interface_sysfs_file - Create wifi feature interface
+ * sysfs file
+ *
+ * Return: none
+ */
+void hdd_create_wifi_feature_interface_sysfs_file(void);
+
+/**
+ * hdd_sysfs_create_wifi_root_obj() - create wifi root kobj
+ * @hdd_ctx: pointer to hdd context
+ *
+ * Return: none
+ */
+void hdd_sysfs_create_wifi_root_obj(struct hdd_context *hdd_ctx);
+
 #else
 static inline int
 hdd_sysfs_validate_and_copy_buf(char *dest_buf, size_t dest_buf_size,
@@ -100,6 +118,14 @@ static void hdd_create_adapter_sysfs_files(struct hdd_adapter *adapter)
 static void hdd_destroy_adapter_sysfs_files(struct hdd_adapter *adapter)
 {
 }
+
+static inline void hdd_create_wifi_feature_interface_sysfs_file(void)
+{
+}
+
+static inline void hdd_sysfs_create_wifi_root_obj(struct hdd_context *hdd_ctx)
+{
+}
 #endif /* End of WLAN SYSFS*/
 
 #endif /* End of _WLAN_HDD_SYSFS_H_ */

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

@@ -9437,6 +9437,17 @@ static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx)
 }
 #endif
 
+/**
+ * wlan_hdd_wifi_kobj_lock_destroy() - Destroy wifi kobj lock
+ * @hdd_ctx: pointer to hdd context
+ *
+ * Return: none
+ */
+static void wlan_hdd_wifi_kobj_lock_destroy(struct hdd_context *hdd_ctx)
+{
+	qdf_mutex_destroy(&hdd_ctx->wifi_kobj_lock);
+}
+
 void hdd_wlan_exit(struct hdd_context *hdd_ctx)
 {
 	struct wiphy *wiphy = hdd_ctx->wiphy;
@@ -9502,6 +9513,7 @@ void hdd_wlan_exit(struct hdd_context *hdd_ctx)
 
 	qdf_spinlock_destroy(&hdd_ctx->hdd_adapter_lock);
 	qdf_spinlock_destroy(&hdd_ctx->connection_status_lock);
+	wlan_hdd_wifi_kobj_lock_destroy(hdd_ctx);
 	wlan_hdd_cache_chann_mutex_destroy(hdd_ctx);
 
 	osif_request_manager_deinit();
@@ -14593,6 +14605,24 @@ static void hdd_deregister_policy_manager_callback(
 }
 #endif
 
+/**
+ * wlan_hdd_free_file_name_and_oem_data() -Free file name and oem data memory
+ * @hdd_ctx: pointer to hdd context
+ *
+ * Return: none
+ */
+static void wlan_hdd_free_file_name_and_oem_data(struct hdd_context *hdd_ctx)
+{
+	if (hdd_ctx->file_name) {
+		qdf_mem_free(hdd_ctx->file_name);
+		hdd_ctx->file_name = NULL;
+	}
+	if (hdd_ctx->oem_data) {
+		qdf_mem_free(hdd_ctx->oem_data);
+		hdd_ctx->oem_data = NULL;
+	}
+}
+
 int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode)
 {
 	void *hif_ctx;
@@ -14757,6 +14787,7 @@ int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode)
 
 	/* Free the cache channels of the command SET_DISABLE_CHANNEL_LIST */
 	wlan_hdd_free_cache_channels(hdd_ctx);
+	wlan_hdd_free_file_name_and_oem_data(hdd_ctx);
 	hdd_driver_mem_cleanup();
 
 	/* Free the resources allocated while storing SAR config. These needs
@@ -15222,6 +15253,17 @@ static QDF_STATUS hdd_open_adapters_for_mode(struct hdd_context *hdd_ctx,
 	return status;
 }
 
+/**
+ * wlan_hdd_wifi_kobj_lock_create() - Create wifi kobj lock
+ * @hdd_ctx: pointer to hdd context
+ *
+ * Return: none
+ */
+static QDF_STATUS wlan_hdd_wifi_kobj_lock_create(struct hdd_context *hdd_ctx)
+{
+	return qdf_mutex_create(&hdd_ctx->wifi_kobj_lock);
+}
+
 int hdd_wlan_startup(struct hdd_context *hdd_ctx)
 {
 	QDF_STATUS status;
@@ -15238,6 +15280,10 @@ int hdd_wlan_startup(struct hdd_context *hdd_ctx)
 	if (QDF_IS_STATUS_ERROR(status))
 		return qdf_status_to_os_return(status);
 
+	status = wlan_hdd_wifi_kobj_lock_create(hdd_ctx);
+	if (QDF_IS_STATUS_ERROR(status))
+		return qdf_status_to_os_return(status);
+
 #ifdef FEATURE_WLAN_CH_AVOID
 	mutex_init(&hdd_ctx->avoid_freq_lock);
 #endif

+ 57 - 2
core/hdd/src/wlan_hdd_oemdata.c

@@ -41,6 +41,8 @@
 #include "wlan_hdd_oemdata.h"
 #include "wlan_osif_request_manager.h"
 #include "wlan_hdd_main.h"
+#include "wlan_hdd_sysfs.h"
+
 #ifdef FEATURE_OEM_DATA_SUPPORT
 #ifdef CNSS_GENL
 #include <net/cnss_nl.h>
@@ -1133,6 +1135,55 @@ oem_data_attr_policy[QCA_WLAN_VENDOR_ATTR_OEM_DATA_PARAMS_MAX + 1] = {
 	[QCA_WLAN_VENDOR_ATTR_OEM_DATA_RESPONSE_EXPECTED] = {.type = NLA_FLAG},
 };
 
+/**
+ * hdd_copy_file_name_and_oem_data() - Copy file name and oem data
+ * @hdd_ctx: pointer to hdd context
+ * @oem_event_data: oem event data param buffe
+ *
+ * Return: none
+ */
+static void hdd_copy_file_name_and_oem_data(
+				struct hdd_context *hdd_ctx,
+				const struct oem_data *oem_event_data)
+{
+	if (!oem_event_data->data_len || !oem_event_data->file_name_len) {
+		hdd_err("Invalid file name or data length");
+		return;
+	}
+
+	if (hdd_ctx->oem_data || hdd_ctx->file_name) {
+		hdd_err("OEM data or file name already present");
+		return;
+	}
+
+	hdd_ctx->oem_data = qdf_mem_malloc(oem_event_data->data_len);
+	if (hdd_ctx->oem_data) {
+		hdd_ctx->oem_data_len = oem_event_data->data_len;
+		qdf_mem_copy(hdd_ctx->oem_data, oem_event_data->data,
+			     oem_event_data->data_len);
+		hdd_ctx->file_name = qdf_mem_malloc(
+					oem_event_data->file_name_len);
+		if (hdd_ctx->file_name)
+			qdf_mem_copy(hdd_ctx->file_name,
+				     oem_event_data->file_name,
+				     oem_event_data->file_name_len);
+		else
+			qdf_mem_free(hdd_ctx->oem_data);
+	}
+}
+
+/**
+ * hdd_create_wifi_feature_interface() - Create wifi feature interface
+ * @hdd_ctx: pointer to hdd context
+ *
+ * Return: none
+ */
+static void hdd_create_wifi_feature_interface(struct hdd_context *hdd_ctx)
+{
+	hdd_sysfs_create_wifi_root_obj(hdd_ctx);
+	hdd_create_wifi_feature_interface_sysfs_file();
+}
+
 void hdd_oem_event_async_cb(const struct oem_data *oem_event_data)
 {
 	struct sk_buff *vendor_event;
@@ -1142,10 +1193,14 @@ void hdd_oem_event_async_cb(const struct oem_data *oem_event_data)
 
 	hdd_enter();
 
-	ret = wlan_hdd_validate_context(hdd_ctx);
-	if (ret)
+	if (!hdd_ctx)
 		return;
 
+	if (oem_event_data->file_name) {
+		hdd_copy_file_name_and_oem_data(hdd_ctx, oem_event_data);
+		return hdd_create_wifi_feature_interface(hdd_ctx);
+	}
+
 	len = nla_total_size(oem_event_data->data_len) + NLMSG_HDRLEN;
 	vendor_event = cfg80211_vendor_event_alloc(
 				hdd_ctx->wiphy, NULL, len,

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

@@ -689,16 +689,25 @@ static void hdd_sysfs_destroy_driver_root_obj(void)
 	}
 }
 
-static void hdd_sysfs_create_wifi_root_obj(struct hdd_context *hdd_ctx)
+void hdd_sysfs_create_wifi_root_obj(struct hdd_context *hdd_ctx)
 {
+	qdf_mutex_acquire(&hdd_ctx->wifi_kobj_lock);
+	if (wifi_kobject) {
+		hdd_debug("wifi kobj already created");
+		goto wifi_kobj_created;
+	}
 	wifi_kobject = pld_get_wifi_kobj(hdd_ctx->parent_dev);
 	if (wifi_kobject) {
 		hdd_debug("wifi_kobject created by platform");
-		return;
+		goto wifi_kobj_created;
 	}
 	wifi_kobject = kobject_create_and_add("wifi", NULL);
 	if (!wifi_kobject)
 		hdd_err("could not allocate wifi kobject");
+
+wifi_kobj_created:
+	qdf_mutex_release(&hdd_ctx->wifi_kobj_lock);
+
 }
 
 static void hdd_sysfs_destroy_wifi_root_obj(void)
@@ -723,6 +732,11 @@ static void hdd_sysfs_destroy_wifi_root_obj(void)
 	wifi_kobject = NULL;
 }
 
+void hdd_create_wifi_feature_interface_sysfs_file(void)
+{
+	hdd_sysfs_create_wifi_feature_interface(wifi_kobject);
+}
+
 #ifdef WLAN_FEATURE_BEACON_RECEPTION_STATS
 static int hdd_sysfs_create_bcn_reception_interface(struct hdd_adapter
 						     *adapter)
@@ -881,7 +895,7 @@ void hdd_create_sysfs_files(struct hdd_context *hdd_ctx)
 	hdd_sysfs_mem_stats_create(wlan_kobject);
 	hdd_sysfs_create_wifi_root_obj(hdd_ctx);
 	if  (QDF_GLOBAL_MISSION_MODE == hdd_get_conparam()) {
-		hdd_sysfs_create_wifi_feature_interface(wifi_kobject);
+		hdd_create_wifi_feature_interface_sysfs_file();
 		hdd_sysfs_create_powerstats_interface();
 		hdd_sysfs_create_dump_in_progress_interface(wifi_kobject);
 		hdd_sysfs_fw_mode_config_create(driver_kobject);

+ 5 - 0
core/wma/src/wma_utils.c

@@ -5032,6 +5032,11 @@ int wma_oem_event_handler(void *wma_ctx, uint8_t *event_buff, uint32_t len)
 	oem_event_data.data_len = event->data_len;
 	oem_event_data.data = param_buf->data;
 
+	if (param_buf->num_file_name) {
+		oem_event_data.file_name = param_buf->file_name;
+		oem_event_data.file_name_len = param_buf->num_file_name;
+	}
+
 	if (pmac->sme.oem_data_event_handler_cb)
 		pmac->sme.oem_data_event_handler_cb(&oem_event_data,
 						    pmac->sme.oem_data_vdev_id);