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
*