qcacmn: Protect wifi_pos global psoc object

Protect wifi_pos global psoc object with spinlock.

Change-Id: I5a250061b482fd2699bebb34c7eac3bd649831f7
CRs-Fixed: 2235825
diff --git a/os_if/linux/wifi_pos/src/os_if_wifi_pos.c b/os_if/linux/wifi_pos/src/os_if_wifi_pos.c
index 592a848..17ea674 100644
--- a/os_if/linux/wifi_pos/src/os_if_wifi_pos.c
+++ b/os_if/linux/wifi_pos/src/os_if_wifi_pos.c
@@ -170,7 +170,7 @@
 		return;
 	}
 
-	wlan_objmgr_psoc_get_ref(psoc, WLAN_WIFI_POS_ID);
+	wlan_objmgr_psoc_get_ref(psoc, WLAN_WIFI_POS_OSIF_ID);
 	err = wifi_pos_parse_req(data, data_len, pid, &req);
 	if (err) {
 		os_if_wifi_pos_send_rsp(wifi_pos_get_app_pid(psoc),
@@ -185,7 +185,7 @@
 				status);
 
 release_psoc_ref:
-	wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_ID);
+	wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_OSIF_ID);
 }
 #else
 static int os_if_wifi_pos_callback(struct sk_buff *skb)
@@ -201,7 +201,7 @@
 		return -EINVAL;
 	}
 
-	wlan_objmgr_psoc_get_ref(psoc, WLAN_WIFI_POS_ID);
+	wlan_objmgr_psoc_get_ref(psoc, WLAN_WIFI_POS_OSIF_ID);
 	err = wifi_pos_parse_req(skb, &req);
 	if (err) {
 		os_if_wifi_pos_send_rsp(wifi_pos_get_app_pid(psoc),
@@ -216,7 +216,7 @@
 				status);
 
 release_psoc_ref:
-	wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_ID);
+	wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_OSIF_ID);
 
 	return qdf_status_to_os_return(status);
 }
diff --git a/target_if/wifi_pos/src/target_if_wifi_pos.c b/target_if/wifi_pos/src/target_if_wifi_pos.c
index 90270c0..f959219 100644
--- a/target_if/wifi_pos/src/target_if_wifi_pos.c
+++ b/target_if/wifi_pos/src/target_if_wifi_pos.c
@@ -164,18 +164,18 @@
 		return QDF_STATUS_NOT_INITIALIZED;
 	}
 
-	wlan_objmgr_psoc_get_ref(psoc, WLAN_WIFI_POS_ID);
+	wlan_objmgr_psoc_get_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID);
 
 	priv_obj = wifi_pos_get_psoc_priv_obj(psoc);
 	if (!priv_obj) {
 		target_if_err("priv_obj is null");
-		wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_ID);
+		wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID);
 		return QDF_STATUS_NOT_INITIALIZED;
 	}
 
 	wifi_pos_rx_ops = target_if_wifi_pos_get_rxops(psoc);
 	if (!wifi_pos_rx_ops || !wifi_pos_rx_ops->oem_rsp_event_rx) {
-		wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_ID);
+		wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID);
 		target_if_err("lmac callbacks not registered");
 		return QDF_STATUS_NOT_INITIALIZED;
 	}
@@ -193,7 +193,7 @@
 						      &oem_rsp, &cookie);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		target_if_err("get indirect data failed status: %d", status);
-		wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_ID);
+		wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID);
 		return QDF_STATUS_E_INVAL;
 	}
 
@@ -207,7 +207,7 @@
 		ret = QDF_STATUS_E_FAILURE;
 	}
 
-	wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_ID);
+	wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID);
 
 	return ret;
 }
diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h
index f5c638d..9a5edcc 100644
--- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h
+++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h
@@ -191,7 +191,7 @@
  * @WLAN_PMO_ID:                power manager offload (PMO) ID
  * @WLAN_LEGACY_SME_ID:         Legacy SME operations
  * @WLAN_SCAN_ID:               scan operations
- * @WLAN_WIFI_POS_ID:           wifi positioning
+ * @WLAN_WIFI_POS_CORE_ID:      wifi positioning (CORE)
  * @WLAN_DFS_ID:                DFS operations
  * @WLAN_P2P_ID:                P2P operations
  * @WLAN_TDLS_SB_ID:            TDLS Southbound operations
@@ -217,6 +217,8 @@
  * @WLAN_IPA_ID:                IPA operations
  * @WLAN_CP_STATS_ID:           Control Plane Statistics Module
  * @WLAN_GREEN_AP_ID:           Green AP operations
+ * @WLAN_WIFI_POS_OSIF_ID:      wifi positioning (OSID)
+ * @WLAN_WIFI_POS_TGT_IF_ID:    wifi positioning (Target IF)
  * @WLAN_REF_ID_MAX:            Max id used to generate ref count tracking array
  */
  /* New value added to the enum must also be reflected in function
@@ -236,7 +238,7 @@
 	WLAN_PMO_ID           = 10,
 	WLAN_LEGACY_SME_ID    = 11,
 	WLAN_SCAN_ID          = 12,
-	WLAN_WIFI_POS_ID      = 13,
+	WLAN_WIFI_POS_CORE_ID = 13,
 	WLAN_DFS_ID           = 14,
 	WLAN_P2P_ID           = 15,
 	WLAN_TDLS_SB_ID       = 16,
@@ -263,6 +265,8 @@
 	WLAN_IPA_ID           = 37,
 	WLAN_CP_STATS_ID      = 38,
 	WLAN_GREEN_AP_ID      = 39,
+	WLAN_WIFI_POS_OSIF_ID = 40,
+	WLAN_WIFI_POS_TGT_IF_ID = 41,
 	WLAN_REF_ID_MAX,
 } wlan_objmgr_ref_dbgid;
 
@@ -289,7 +293,7 @@
 					"WLAN_PMO_ID",
 					"WLAN_LEGACY_SME_ID",
 					"WLAN_SCAN_ID",
-					"WLAN_WIFI_POS_ID",
+					"WLAN_WIFI_POS_CORE_ID",
 					"WLAN_DFS_ID",
 					"WLAN_P2P_ID",
 					"WLAN_TDLS_SB_ID",
@@ -316,7 +320,9 @@
 					"WLAN_IPA_ID",
 					"WLAN_CP_STATS_ID",
 					"WLAN_GREEN_AP_ID",
-					"WLAN_REF_ID_MAX" };
+					"WLAN_WIFI_POS_OSIF_ID",
+					"WLAN_WIFI_POS_TGT_IF_ID",
+					"WLAN_REF_ID_MAX"};
 
 	return (char *)strings[id];
 }
diff --git a/umac/wifi_pos/src/wifi_pos_api.c b/umac/wifi_pos/src/wifi_pos_api.c
index f3e5bce..0ec581c 100644
--- a/umac/wifi_pos/src/wifi_pos_api.c
+++ b/umac/wifi_pos/src/wifi_pos_api.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -33,6 +33,8 @@
 {
 	QDF_STATUS status;
 
+	wifi_pos_lock_init();
+
 	/* register psoc create handler functions. */
 	status = wlan_objmgr_register_psoc_create_handler(
 		WLAN_UMAC_COMP_WIFI_POS,
@@ -81,6 +83,9 @@
 		wifi_pos_err("unregister_psoc_destroy_handler failed, status: %d",
 			     status);
 	}
+
+	wifi_pos_lock_deinit();
+
 	return QDF_STATUS_SUCCESS;
 }
 
diff --git a/umac/wifi_pos/src/wifi_pos_main.c b/umac/wifi_pos/src/wifi_pos_main.c
index 963a1a4..addb6cb 100644
--- a/umac/wifi_pos/src/wifi_pos_main.c
+++ b/umac/wifi_pos/src/wifi_pos_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -200,7 +200,7 @@
 			req->pid, req->buf_len);
 
 	/* get first pdev since we need that only for freq and dfs state */
-	pdev = wlan_objmgr_get_pdev_by_id(psoc, 0, WLAN_WIFI_POS_ID);
+	pdev = wlan_objmgr_get_pdev_by_id(psoc, 0, WLAN_WIFI_POS_CORE_ID);
 	if (!pdev) {
 		wifi_pos_err("pdev get API failed");
 		return QDF_STATUS_E_INVAL;
@@ -210,7 +210,7 @@
 	buf = qdf_mem_malloc(len);
 	if (!buf) {
 		wifi_pos_alert("malloc failed");
-		wlan_objmgr_pdev_release_ref(pdev, WLAN_WIFI_POS_ID);
+		wlan_objmgr_pdev_release_ref(pdev, WLAN_WIFI_POS_CORE_ID);
 		return QDF_STATUS_E_NOMEM;
 	}
 
@@ -235,7 +235,7 @@
 					ANI_MSG_CHANNEL_INFO_RSP,
 					len, buf);
 	qdf_mem_free(buf);
-	wlan_objmgr_pdev_release_ref(pdev, WLAN_WIFI_POS_ID);
+	wlan_objmgr_pdev_release_ref(pdev, WLAN_WIFI_POS_CORE_ID);
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -284,7 +284,7 @@
 	vdev_idx = 0;
 	wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP,
 				     wifi_pos_vdev_iterator,
-				     vdevs_info, true, WLAN_WIFI_POS_ID);
+				     vdevs_info, true, WLAN_WIFI_POS_CORE_ID);
 	rsp_len = (sizeof(struct app_reg_rsp_vdev_info) * vdev_idx)
 			+ sizeof(uint8_t);
 	app_reg_rsp = qdf_mem_malloc(rsp_len);
@@ -531,7 +531,7 @@
 
 	wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP,
 				     wifi_pos_pdev_iterator,
-				     ch_lst, true, WLAN_WIFI_POS_ID);
+				     ch_lst, true, WLAN_WIFI_POS_CORE_ID);
 
 	for (i = 0; i < NUM_CHANNELS && num_ch < OEM_CAP_MAX_NUM_CHANNELS;
 	     i++) {
diff --git a/umac/wifi_pos/src/wifi_pos_utils.c b/umac/wifi_pos/src/wifi_pos_utils.c
index 2f19b3d..1a7ac0f 100644
--- a/umac/wifi_pos/src/wifi_pos_utils.c
+++ b/umac/wifi_pos/src/wifi_pos_utils.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -26,6 +26,9 @@
 #include "wlan_objmgr_psoc_obj.h"
 #include "wifi_pos_utils_i.h"
 
+/* lock to protect use of psoc global pointer variable */
+static qdf_spinlock_t psoc_ptr_lock;
+
 /*
  * WIFI pos command are not associated with any pdev/psoc/vdev, so the callback
  * registered with GENL socket does not receive any pdev/pdev/vdev object.
@@ -35,25 +38,59 @@
  */
 static struct wlan_objmgr_psoc *wifi_pos_psoc_obj;
 
+void wifi_pos_lock_init(void)
+{
+	qdf_spinlock_create(&psoc_ptr_lock);
+}
+
+void wifi_pos_lock_deinit(void)
+{
+	qdf_spinlock_destroy(&psoc_ptr_lock);
+}
+
 struct wlan_objmgr_psoc *wifi_pos_get_psoc(void)
 {
-	return wifi_pos_psoc_obj;
+	struct wlan_objmgr_psoc  *tmp;
+
+	qdf_spin_lock_bh(&psoc_ptr_lock);
+	tmp = wifi_pos_psoc_obj;
+	qdf_spin_unlock_bh(&psoc_ptr_lock);
+
+	return tmp;
 }
 
 void wifi_pos_set_psoc(struct wlan_objmgr_psoc *psoc)
 {
-	if (wifi_pos_psoc_obj)
-		wifi_pos_warn("global psoc obj already set");
-	else
+	struct wlan_objmgr_psoc *tmp;
+
+	qdf_spin_lock_bh(&psoc_ptr_lock);
+	tmp = wifi_pos_psoc_obj;
+	if (!wifi_pos_psoc_obj) {
 		wifi_pos_psoc_obj = psoc;
+		wlan_objmgr_psoc_get_ref(wifi_pos_psoc_obj,
+					 WLAN_WIFI_POS_CORE_ID);
+	}
+	qdf_spin_unlock_bh(&psoc_ptr_lock);
+
+	if (tmp)
+		wifi_pos_warn("global psoc obj already set");
 }
 
 void wifi_pos_clear_psoc(void)
 {
-	if (!wifi_pos_psoc_obj)
-		wifi_pos_warn("global psoc obj already cleared");
-	else
+	struct wlan_objmgr_psoc *tmp;
+
+	qdf_spin_lock_bh(&psoc_ptr_lock);
+	tmp = wifi_pos_psoc_obj;
+	if (wifi_pos_psoc_obj) {
+		wlan_objmgr_psoc_release_ref(wifi_pos_psoc_obj,
+					     WLAN_WIFI_POS_CORE_ID);
 		wifi_pos_psoc_obj = NULL;
+	}
+	qdf_spin_unlock_bh(&psoc_ptr_lock);
+
+	if (!tmp)
+		wifi_pos_warn("global psoc obj already cleared");
 }
 
 /**
diff --git a/umac/wifi_pos/src/wifi_pos_utils_i.h b/umac/wifi_pos/src/wifi_pos_utils_i.h
index 467573e..c74d6e3 100644
--- a/umac/wifi_pos/src/wifi_pos_utils_i.h
+++ b/umac/wifi_pos/src/wifi_pos_utils_i.h
@@ -310,6 +310,22 @@
 		struct wlan_objmgr_psoc *psoc);
 
 /**
+ * wifi_pos_lock_init: API to init lock used protect use of psoc global pointer
+ * variable
+ *
+ * Return: none.
+ */
+void wifi_pos_lock_init(void);
+
+/**
+ * wifi_pos_lock_deinit: API to deinit lock used protect use of psoc global
+ * pointer variable
+ *
+ * Return: none.
+ */
+void wifi_pos_lock_deinit(void);
+
+/**
  * wifi_pos_set_psoc: API to set global PSOC object
  * @psoc: pointer to psoc object
  *