Browse Source

qcacld-3.0: Add support to create ranging peer

Add support to send ranging peer create command from WMA

Change-Id: I67966983b157efaecaad7209b679483f010e84a5
CRs-Fixed: 3150075
Pragaspathi Thilagaraj 3 years ago
parent
commit
e33def8324

+ 23 - 0
Kbuild

@@ -2337,16 +2337,33 @@ WIFI_POS_API_INC := -I$(WLAN_COMMON_INC)/umac/wifi_pos/inc
 
 
 ifeq ($(CONFIG_WIFI_POS_CONVERGED), y)
+
+WIFI_POS_CLD_DIR := components/wifi_pos
+WIFI_POS_CLD_CORE_DIR := $(WIFI_POS_CLD_DIR)/core
+WIFI_POS_CLD_CORE_SRC := $(WIFI_POS_CLD_CORE_DIR)/src
+WIFI_POS_CLD_DISP_DIR := $(WIFI_POS_CLD_DIR)/dispatcher
+
 WIFI_POS_OBJS := $(WIFI_POS_CORE_DIR)/wifi_pos_api.o \
 		 $(WIFI_POS_CORE_DIR)/wifi_pos_main.o \
 		 $(WIFI_POS_CORE_DIR)/wifi_pos_ucfg.o \
 		 $(WIFI_POS_CORE_DIR)/wifi_pos_utils.o \
+		 $(WIFI_POS_CLD_DISP_DIR)/src/wifi_pos_ucfg_api.o \
 		 $(WIFI_POS_OS_IF_DIR)/os_if_wifi_pos.o \
 		 $(WIFI_POS_OS_IF_DIR)/os_if_wifi_pos_utils.o \
 		 $(WIFI_POS_OS_IF_DIR)/wlan_cfg80211_wifi_pos.o \
 		 $(WIFI_POS_TGT_DIR)/target_if_wifi_pos.o \
 		 $(WIFI_POS_TGT_DIR)/target_if_wifi_pos_rx_ops.o \
 		 $(WIFI_POS_TGT_DIR)/target_if_wifi_pos_tx_ops.o
+
+ifeq ($(CONFIG_WIFI_POS_PASN), y)
+WIFI_POS_OBJS += $(WIFI_POS_CORE_DIR)/wifi_pos_pasn_api.o
+WIFI_POS_OBJS += $(WIFI_POS_CLD_CORE_SRC)/wlan_wifi_pos_interface.o
+endif
+
+WIFI_POS_CLD_INC :=	-I$(WLAN_ROOT)/$(WIFI_POS_CLD_CORE_DIR)/inc \
+			-I$(WLAN_ROOT)/$(WIFI_POS_CLD_DISP_DIR)/inc
+
+cppflags-$(CONFIG_WIFI_POS_PASN) += -DWLAN_FEATURE_RTT_11AZ_SUPPORT
 endif
 
 $(call add-wlan-objs,wifi_pos,$(WIFI_POS_OBJS))
@@ -2831,6 +2848,11 @@ endif
 ifeq ($(CONFIG_WLAN_MWS_INFO_DEBUGFS), y)
 WMA_OBJS +=	$(WMA_SRC_DIR)/wma_coex.o
 endif
+ifeq ($(CONFIG_WIFI_POS_CONVERGED), y)
+ifeq ($(CONFIG_WIFI_POS_PASN), y)
+WMA_OBJS +=	$(WMA_SRC_DIR)/wma_pasn_peer_api.o
+endif
+endif
 
 $(call add-wlan-objs,wma,$(WMA_OBJS))
 
@@ -2967,6 +2989,7 @@ INCS += 	$(HAL_INC) \
 endif
 
 ################ WIFI POS ################
+INCS +=		$(WIFI_POS_CLD_INC)
 INCS +=		$(WIFI_POS_API_INC)
 INCS +=		$(WIFI_POS_TGT_INC)
 INCS +=		$(WIFI_POS_OS_IF_INC)

+ 9 - 6
components/wifi_pos/core/inc/wlan_wifi_pos_interface.h

@@ -34,19 +34,22 @@ QDF_STATUS
 wifi_pos_register_legacy_ops(struct wlan_objmgr_psoc *psoc);
 
 /**
- * ucfg_wifi_pos_set_legacy_ops() - Wrapper to set legacy ops
- * @psoc: PSOC pointer
+ * wifi_pos_deregister_legacy_ops() - Deregister wifi pos legacy callbacks
+ * @psoc: Psoc pointer
  *
  * Return: QDF_STATUS
  */
+QDF_STATUS
+wifi_pos_deregister_legacy_ops(struct wlan_objmgr_psoc *psoc);
+#else
 static inline QDF_STATUS
-ucfg_wifi_pos_set_legacy_ops(struct wlan_objmgr_psoc *psoc)
+wifi_pos_register_legacy_ops(struct wlan_objmgr_psoc *psoc)
 {
-	return wifi_pos_register_legacy_ops(psoc);
+	return QDF_STATUS_SUCCESS;
 }
-#else
+
 static inline QDF_STATUS
-ucfg_wifi_pos_set_legacy_ops(struct wlan_objmgr_psoc *psoc)
+wifi_pos_deregister_legacy_ops(struct wlan_objmgr_psoc *psoc)
 {
 	return QDF_STATUS_SUCCESS;
 }

+ 9 - 4
components/wifi_pos/core/src/wlan_wifi_pos_interface.c

@@ -17,8 +17,7 @@
  * DOC: define internal APIs related to the mlme component, legacy APIs are
  *	called for the time being, but will be cleaned up after convergence
  */
-#include "wma_api.h"
-#include "wma.h"
+#include "wma_pasn_peer_api.h"
 #include "wifi_pos_api.h"
 #include "wlan_wifi_pos_interface.h"
 
@@ -35,7 +34,7 @@ static QDF_STATUS wlan_wifi_pos_pasn_peer_create(struct wlan_objmgr_psoc *psoc,
 						 struct qdf_mac_addr *peer_addr,
 						 uint8_t vdev_id)
 {
-	return wma_create_ranging_peer(psoc, peer_addr, vdev_id);
+	return wma_pasn_peer_create(psoc, peer_addr, vdev_id);
 }
 
 /**
@@ -51,7 +50,7 @@ static QDF_STATUS wlan_wifi_pos_pasn_peer_delete(struct wlan_objmgr_psoc *psoc,
 						 uint8_t vdev_id,
 						 bool no_fw_peer_delete)
 {
-	return wma_remove_pasn_peer(psoc, peer_addr, vdev_id,
+	return wma_pasn_peer_remove(psoc, peer_addr, vdev_id,
 				    no_fw_peer_delete);
 }
 
@@ -65,4 +64,10 @@ wifi_pos_register_legacy_ops(struct wlan_objmgr_psoc *psoc)
 {
 	return wifi_pos_set_legacy_ops(psoc, &wifi_pos_ops);
 }
+
+QDF_STATUS
+wifi_pos_deregister_legacy_ops(struct wlan_objmgr_psoc *psoc)
+{
+	return wifi_pos_set_legacy_ops(psoc, NULL);
+}
 #endif

+ 16 - 0
components/wifi_pos/dispatcher/inc/wifi_pos_ucfg_api.h

@@ -34,11 +34,27 @@
  */
 QDF_STATUS
 ucfg_wifi_pos_psoc_open(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_wifi_pos_psoc_close  - Wifi pos module PSOC close api
+ * @psoc: Pointer to PSOC object
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+ucfg_wifi_pos_psoc_close(struct wlan_objmgr_psoc *psoc);
+#
 #else
 static inline QDF_STATUS
 ucfg_wifi_pos_psoc_open(struct wlan_objmgr_psoc *psoc)
 {
 	return QDF_STATUS_SUCCESS;
 }
+
+static inline QDF_STATUS
+ucfg_wifi_pos_psoc_close(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
 #endif /* WIFI_POS_CONVERGED && WLAN_FEATURE_RTT_11AZ_SUPPORT */
 #endif /* _WLAN_WIFI_POS_UCFG_API_H_ */

+ 17 - 1
components/wifi_pos/dispatcher/src/wifi_pos_ucfg_api.c

@@ -31,10 +31,26 @@ ucfg_wifi_pos_psoc_open(struct wlan_objmgr_psoc *psoc)
 	if (QDF_IS_STATUS_ERROR(status))
 		wifi_pos_err("Register OSIF ops failed");
 
-	status = ucfg_wifi_pos_set_legacy_ops(psoc);
+	status = wifi_pos_register_legacy_ops(psoc);
 	if (QDF_IS_STATUS_ERROR(status))
 		wifi_pos_err("Set legacy ops failed");
 
 	return status;
 }
+
+QDF_STATUS
+ucfg_wifi_pos_psoc_close(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS status;
+
+	status = wifi_pos_deregister_legacy_ops(psoc);
+	if (QDF_IS_STATUS_ERROR(status))
+		wifi_pos_err("Set legacy ops failed");
+
+	status = osif_wifi_pos_deregister_ops(psoc);
+	if (QDF_IS_STATUS_ERROR(status))
+		wifi_pos_err("Register OSIF ops failed");
+
+	return status;
+}
 #endif /* WIFI_POS_CONVERGED && WLAN_FEATURE_RTT_11AZ_SUPPORT */

+ 9 - 1
core/hdd/src/wlan_hdd_main.c

@@ -221,6 +221,7 @@
 #include "wlan_vdev_mgr_ucfg_api.h"
 #include <wlan_objmgr_psoc_obj_i.h>
 #include <wlan_objmgr_vdev_obj_i.h>
+#include "wifi_pos_ucfg_api.h"
 #include "osif_vdev_mgr_util.h"
 #include <son_ucfg_api.h>
 #include "osif_twt_util.h"
@@ -4957,7 +4958,7 @@ static int hdd_deactivate_wifi_pos(void)
 	if (ret)
 		hdd_err("os_if_wifi_pos_deregister_nl failed");
 
-	return  ret;
+	return ret;
 }
 
 /**
@@ -18449,8 +18450,14 @@ QDF_STATUS hdd_component_psoc_open(struct wlan_objmgr_psoc *psoc)
 	if (QDF_IS_STATUS_ERROR(status))
 		goto err_twt;
 
+	status = ucfg_wifi_pos_psoc_open(psoc);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto err_wifi_pos;
+
 	return status;
 
+err_wifi_pos:
+	ucfg_twt_psoc_close(psoc);
 err_twt:
 	ucfg_nan_psoc_close(psoc);
 err_nan:
@@ -18473,6 +18480,7 @@ err_dlm:
 
 void hdd_component_psoc_close(struct wlan_objmgr_psoc *psoc)
 {
+	ucfg_wifi_pos_psoc_close(psoc);
 	ucfg_twt_psoc_close(psoc);
 	ucfg_nan_psoc_close(psoc);
 	ucfg_tdls_psoc_close(psoc);

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

@@ -179,6 +179,9 @@
 /* send connect respone after bss peer is deleted */
 #define WMA_DELETE_STA_CONNECT_RSP 0x09
 
+/* Peer create response for 11az PASN peer */
+#define WMA_PASN_PEER_CREATE_RESPONSE 0x0a
+
 /* FW response timeout values in milli seconds */
 #define WMA_VDEV_PLCY_MGR_TIMEOUT        SIR_VDEV_PLCY_MGR_TIMEOUT
 #define WMA_VDEV_HW_MODE_REQUEST_TIMEOUT WMA_VDEV_PLCY_MGR_TIMEOUT
@@ -1118,6 +1121,7 @@ struct wma_tx_ack_work_ctx {
  * @event_timeout: event timeout
  * @node: list
  * @user_data: user data
+ * @addr: Mac address
  * @msg_type: message type
  * @vdev_id: vdev id
  * @type: type
@@ -1126,6 +1130,7 @@ struct wma_target_req {
 	qdf_mc_timer_t event_timeout;
 	qdf_list_node_t node;
 	void *user_data;
+	struct qdf_mac_addr addr;
 	uint32_t msg_type;
 	uint8_t vdev_id;
 	uint8_t type;
@@ -1663,6 +1668,32 @@ QDF_STATUS wma_create_peer(tp_wma_handle wma,
 			   uint8_t peer_mld_addr[QDF_MAC_ADDR_SIZE],
 			   bool is_assoc_peer);
 
+/**
+ * wma_create_objmgr_peer() - create objmgr peer information in host driver
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @peer_addr: peer mac address
+ * @wma_peer_type: peer type of enum wmi_peer_type
+ *
+ * Return: Pointer to objmgr_peer
+ */
+struct wlan_objmgr_peer *wma_create_objmgr_peer(tp_wma_handle wma,
+						uint8_t vdev_id,
+						uint8_t *peer_addr,
+						uint32_t wma_peer_type);
+
+/**
+ * wma_remove_objmgr_peer() - Remove Object manager peer
+ * @wma:  WMA handle
+ * @obj_vdev: Vdev object pointer
+ * @peer_addr: Peer mac address
+ *
+ * Return: None
+ */
+void wma_remove_objmgr_peer(tp_wma_handle wma,
+			    struct wlan_objmgr_vdev *obj_vdev,
+			    uint8_t *peer_addr);
+
 QDF_STATUS wma_peer_unmap_conf_cb(uint8_t vdev_id,
 				  uint32_t peer_id_cnt,
 				  uint16_t *peer_id_list);

+ 13 - 1
core/wma/inc/wma_internal.h

@@ -1413,8 +1413,20 @@ int wma_peer_create_confirm_handler(void *handle, uint8_t *evt_param_info,
 
 int wma_peer_delete_handler(void *handle, uint8_t *cmd_param_info,
 				uint32_t len);
+
 void wma_remove_req(tp_wma_handle wma, uint8_t vdev_id,
-			    uint8_t type);
+		    uint8_t type);
+
+/**
+ * wma_remove_peer_req  - Remove the peer create
+ * request from WMA queue
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @type: peer type
+ * @peer_addr: peer address
+ */
+void wma_remove_peer_req(tp_wma_handle wma, uint8_t vdev_id,
+			 uint8_t type, struct qdf_mac_addr *peer_addr);
 
 QDF_STATUS wma_process_hal_pwr_dbg_cmd(WMA_HANDLE handle,
 				       struct sir_mac_pwr_dbg_cmd *

+ 95 - 0
core/wma/inc/wma_pasn_peer_api.h

@@ -0,0 +1,95 @@
+/*
+ * 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 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.
+ */
+
+#ifndef __WMA_PASN_PEER_API_H__
+#define __WMA_PASN_PEER_API_H__
+
+#include "qdf_types.h"
+#include "osapi_linux.h"
+#include "wmi_services.h"
+#include "wmi_unified.h"
+#include "wmi_unified_api.h"
+#include "wlan_objmgr_psoc_obj.h"
+#include "wma.h"
+
+#if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT)
+/**
+ * wma_pasn_peer_remove  - Remove RTT pasn peer and send peer delete command to
+ * firmware
+ * @wma: WMA handle
+ * @peer_addr: Peer mac address
+ * @vdev_id: vdev id
+ * @no_fw_peer_delete: Don't send peer delete to firmware
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wma_pasn_peer_remove(struct wlan_objmgr_psoc *psoc,
+		     struct qdf_mac_addr *peer_addr,
+		     uint8_t vdev_id,  bool no_fw_peer_delete);
+
+/**
+ * wma_pasn_peer_create() - Create RTT PASN peer
+ * @psoc: PSOC pointer
+ * @peer_addr: Peer address
+ * @vdev_id: vdev id
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wma_pasn_peer_create(struct wlan_objmgr_psoc *psoc,
+		     struct qdf_mac_addr *peer_addr,
+		     uint8_t vdev_id);
+
+/**
+ * wma_pasn_handle_peer_create_conf() - Handle PASN peer create confirm event
+ * @wma: WMA handle
+ * @peer_mac: peer mac address
+ * @status: status
+ * @vdev_id: vdev id
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wma_pasn_handle_peer_create_conf(tp_wma_handle wma,
+				 struct qdf_mac_addr *peer_mac,
+				 QDF_STATUS status, uint8_t vdev_id);
+#else
+static inline QDF_STATUS
+wma_pasn_peer_create(struct wlan_objmgr_psoc *psoc,
+		     struct qdf_mac_addr *peer_addr,
+		     uint8_t vdev_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+wma_pasn_peer_remove(struct wlan_objmgr_psoc *psoc,
+		     struct qdf_mac_addr *peer_addr,
+		     uint8_t vdev_id,  bool no_fw_peer_delete)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+wma_pasn_handle_peer_create_conf(tp_wma_handle wma,
+				 struct qdf_mac_addr *peer_mac,
+				 QDF_STATUS status, uint8_t vdev_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+#endif

+ 72 - 32
core/wma/src/wma_dev_if.c

@@ -41,6 +41,7 @@
 #include "wma_types.h"
 #include "lim_api.h"
 #include "lim_session_utils.h"
+#include "wma_pasn_peer_api.h"
 
 #include "cds_utils.h"
 
@@ -95,6 +96,7 @@
 #include <../../core/src/wlan_cm_vdev_api.h>
 #include "wlan_nan_api.h"
 #include "wlan_mlo_mgr_peer.h"
+#include "wifi_pos_api.h"
 #ifdef DCS_INTERFERENCE_DETECTION
 #include <wlan_dcs_ucfg_api.h>
 #endif
@@ -270,6 +272,7 @@ static QDF_STATUS wma_find_req_on_timer_expiry(tp_wma_handle wma,
  * @wma: wma handle
  * @vdev_id: vdev id
  * @type: request type
+ * @peer_addr: Peer mac address
  *
  * Find target request for given vdev id & type of request.
  * Remove that request from active list.
@@ -277,7 +280,8 @@ static QDF_STATUS wma_find_req_on_timer_expiry(tp_wma_handle wma,
  * Return: return target request if found or NULL.
  */
 static struct wma_target_req *wma_find_req(tp_wma_handle wma,
-					   uint8_t vdev_id, uint8_t type)
+					   uint8_t vdev_id, uint8_t type,
+					   struct qdf_mac_addr *peer_addr)
 {
 	struct wma_target_req *req_msg = NULL;
 	bool found = false;
@@ -301,6 +305,11 @@ static struct wma_target_req *wma_find_req(tp_wma_handle wma,
 			continue;
 
 		found = true;
+		if (type == WMA_PEER_CREATE_RESPONSE &&
+		    peer_addr &&
+		    !qdf_is_macaddr_equal(&req_msg->addr, peer_addr))
+			found = false;
+
 		status = qdf_list_remove_node(&wma->wma_hold_req_queue, node1);
 		if (QDF_STATUS_SUCCESS != status) {
 			qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
@@ -604,17 +613,9 @@ QDF_STATUS wma_p2p_self_peer_remove(struct wlan_objmgr_vdev *vdev)
 }
 #endif
 
-/**
- * wma_remove_objmgr_peer() - remove objmgr peer information from host driver
- * @wma: wma handle
- * @vdev_id: vdev id
- * @peer_addr: peer mac address
- *
- * Return: none
- */
-static void wma_remove_objmgr_peer(tp_wma_handle wma,
-				   struct wlan_objmgr_vdev *obj_vdev,
-				   uint8_t *peer_addr)
+void wma_remove_objmgr_peer(tp_wma_handle wma,
+			    struct wlan_objmgr_vdev *obj_vdev,
+			    uint8_t *peer_addr)
 {
 	struct wlan_objmgr_psoc *psoc;
 	struct wlan_objmgr_peer *obj_peer;
@@ -1728,6 +1729,9 @@ static int wma_get_obj_mgr_peer_type(tp_wma_handle wma, uint8_t vdev_id,
 	if (wma_peer_type == WMI_PEER_TYPE_TDLS)
 		return WLAN_PEER_TDLS;
 
+	if (wma_peer_type == WMI_PEER_TYPE_PASN)
+		return WLAN_PEER_RTT_PASN;
+
 	if (!qdf_mem_cmp(addr, peer_addr, QDF_MAC_ADDR_SIZE)) {
 		obj_peer_type = WLAN_PEER_SELF;
 	} else if (wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_STA) {
@@ -1752,20 +1756,10 @@ static int wma_get_obj_mgr_peer_type(tp_wma_handle wma, uint8_t vdev_id,
 
 }
 
-/**
- * wma_create_objmgr_peer() - create objmgr peer information in host driver
- * @wma: wma handle
- * @vdev_id: vdev id
- * @peer_addr: peer mac address
- * @wma_peer_type: peer type
- *
- * Return: objmgr peer pointer
- */
-
-static struct wlan_objmgr_peer *wma_create_objmgr_peer(tp_wma_handle wma,
-						       uint8_t vdev_id,
-						       uint8_t *peer_addr,
-						       uint32_t wma_peer_type)
+struct wlan_objmgr_peer *wma_create_objmgr_peer(tp_wma_handle wma,
+						uint8_t vdev_id,
+						uint8_t *peer_addr,
+						uint32_t wma_peer_type)
 {
 	uint32_t obj_peer_type = 0;
 	struct wlan_objmgr_peer *obj_peer = NULL;
@@ -2115,7 +2109,8 @@ wma_create_sta_mode_bss_peer(tp_wma_handle wma,
 				WMA_PEER_CREATE_RESPONSE_TIMEOUT);
 	if (!msg) {
 		wma_err("vdev:%d failed to fill peer create req", vdev_id);
-		wma_remove_req(wma, vdev_id, WMA_PEER_CREATE_RESPONSE);
+		wma_remove_peer_req(wma, vdev_id, WMA_PEER_CREATE_RESPONSE,
+				    (struct qdf_mac_addr *)peer_addr);
 		wma_remove_peer(wma, peer_addr, vdev_id, false);
 		wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
 		status = QDF_STATUS_E_FAILURE;
@@ -3321,7 +3316,7 @@ int wma_peer_assoc_conf_handler(void *handle, uint8_t *cmd_param_info,
 		 event->vdev_id, QDF_MAC_ADDR_REF(macaddr));
 
 	req_msg = wma_find_req(wma, event->vdev_id,
-				    WMA_PEER_ASSOC_CNF_START);
+			       WMA_PEER_ASSOC_CNF_START, NULL);
 
 	if (!req_msg) {
 		wma_err("Failed to lookup request message for vdev %d",
@@ -3375,6 +3370,7 @@ int wma_peer_create_confirm_handler(void *handle, uint8_t *evt_param_info,
 	struct qdf_mac_addr peer_mac;
 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
 	int ret = -EINVAL;
+	uint8_t req_msg_type;
 
 	param_buf = (WMI_PEER_CREATE_CONF_EVENTID_param_tlvs *)evt_param_info;
 	if (!param_buf) {
@@ -3403,15 +3399,23 @@ int wma_peer_create_confirm_handler(void *handle, uint8_t *evt_param_info,
 		return -EINVAL;
 	}
 
-	wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
-
 	rsp_data = (struct peer_create_rsp_params *)req_msg->user_data;
+	req_msg_type = req_msg->type;
 
 	qdf_mc_timer_stop(&req_msg->event_timeout);
 	qdf_mc_timer_destroy(&req_msg->event_timeout);
 	qdf_mem_free(rsp_data);
 	qdf_mem_free(req_msg);
 
+	if (req_msg_type == WMA_PASN_PEER_CREATE_RESPONSE) {
+		wma_pasn_handle_peer_create_conf(wma, &peer_mac,
+						 peer_create_rsp->status,
+						 peer_create_rsp->vdev_id);
+		wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
+		return 0;
+	}
+
+	wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
 	if (!peer_create_rsp->status) {
 		if (!dp_soc) {
 			wma_err("DP SOC context is NULL");
@@ -3758,6 +3762,24 @@ void wma_hold_req_timer(void *data)
 					  QDF_STATUS_E_TIMEOUT,
 					  (uint8_t *)tgt_req->user_data);
 		qdf_mem_free(tgt_req->user_data);
+	} else if ((tgt_req->msg_type == WMA_PEER_CREATE_REQ) &&
+		   (tgt_req->type == WMA_PASN_PEER_CREATE_RESPONSE)) {
+		struct peer_create_rsp_params *peer_create_rsp;
+		struct qdf_mac_addr *peer_mac;
+
+		if (wma_crash_on_fw_timeout(wma->fw_timeout_crash))
+			wma_trigger_recovery_assert_on_fw_timeout(
+				WMA_PEER_CREATE_RESPONSE,
+				WMA_PEER_CREATE_RESPONSE_TIMEOUT);
+
+		peer_create_rsp =
+			(struct peer_create_rsp_params *)tgt_req->user_data;
+		peer_mac = &peer_create_rsp->peer_mac;
+
+		wma_pasn_handle_peer_create_conf(
+				wma, peer_mac, QDF_STATUS_E_TIMEOUT,
+				tgt_req->vdev_id);
+		qdf_mem_free(tgt_req->user_data);
 	} else {
 		wma_err("Unhandled timeout for msg_type:%d and type:%d",
 				tgt_req->msg_type, tgt_req->type);
@@ -3811,6 +3833,24 @@ struct wma_target_req *wma_fill_hold_req(tp_wma_handle wma,
 	return req;
 }
 
+void wma_remove_peer_req(tp_wma_handle wma, uint8_t vdev_id,
+			 uint8_t type, struct qdf_mac_addr *peer_addr)
+{
+	struct wma_target_req *req_msg;
+
+	wma_debug("Remove req for vdev: %d type: %d", vdev_id, type);
+	req_msg = wma_find_req(wma, vdev_id, type, peer_addr);
+	if (!req_msg) {
+		wma_err("target req not found for vdev: %d type: %d",
+			vdev_id, type);
+		return;
+	}
+
+	qdf_mc_timer_stop(&req_msg->event_timeout);
+	qdf_mc_timer_destroy(&req_msg->event_timeout);
+	qdf_mem_free(req_msg);
+}
+
 /**
  * wma_remove_req() - remove request
  * @wma: wma handle
@@ -3825,7 +3865,7 @@ void wma_remove_req(tp_wma_handle wma, uint8_t vdev_id,
 	struct wma_target_req *req_msg;
 
 	wma_debug("Remove req for vdev: %d type: %d", vdev_id, type);
-	req_msg = wma_find_req(wma, vdev_id, type);
+	req_msg = wma_find_req(wma, vdev_id, type, NULL);
 	if (!req_msg) {
 		wma_err("target req not found for vdev: %d type: %d",
 			 vdev_id, type);
@@ -5114,7 +5154,7 @@ static void wma_delete_sta_req_ap_mode(tp_wma_handle wma,
 			wma_err("Failed to allocate request. vdev_id %d",
 				 del_sta->smesessionId);
 			wma_remove_req(wma, del_sta->smesessionId,
-				WMA_DELETE_STA_RSP_START);
+				       WMA_DELETE_STA_RSP_START);
 			del_sta->status = QDF_STATUS_E_NOMEM;
 			goto send_del_rsp;
 		}

+ 203 - 0
core/wma/src/wma_pasn_peer_api.c

@@ -0,0 +1,203 @@
+/*
+ * 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 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: wma_pasn_peer_api.c
+ *  This file contains PASN peer related operations.
+ */
+
+#include "wma.h"
+#include "wma_api.h"
+#include "wmi_unified_api.h"
+#include "wmi_unified.h"
+#include "qdf_types.h"
+#include "qdf_mem.h"
+#include "wma_types.h"
+#include "wma_internal.h"
+#include "wma_pasn_peer_api.h"
+#include "wifi_pos_api.h"
+#include "init_deinit_lmac.h"
+
+QDF_STATUS
+wma_pasn_peer_remove(struct wlan_objmgr_psoc *psoc,
+		     struct qdf_mac_addr *peer_addr,
+		     uint8_t vdev_id,  bool no_fw_peer_delete)
+{
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+	struct peer_delete_cmd_params del_param = {0};
+	QDF_STATUS qdf_status;
+	uint8_t peer_vdev_id;
+
+	if (!wma) {
+		wma_err("wma_handle is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!wma_objmgr_peer_exist(wma, peer_addr->bytes, &peer_vdev_id)) {
+		wma_err("peer doesn't exist peer_addr " QDF_MAC_ADDR_FMT " vdevid %d",
+			QDF_MAC_ADDR_REF(peer_addr), vdev_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (peer_vdev_id != vdev_id) {
+		wma_err("peer " QDF_MAC_ADDR_FMT " is on vdev id %d but delete req on vdevid %d",
+			QDF_MAC_ADDR_REF(peer_addr), peer_vdev_id, vdev_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	del_param.vdev_id = vdev_id;
+	qdf_status = wmi_unified_peer_delete_send(wma->wmi_handle,
+						  peer_addr->bytes,
+						  &del_param);
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
+		wma_err("Peer delete could not be sent to firmware %d",
+			qdf_status);
+		qdf_status = QDF_STATUS_E_FAILURE;
+	}
+
+	wma_remove_objmgr_peer(wma, wma->interfaces[vdev_id].vdev,
+			       peer_addr->bytes);
+
+	return qdf_status;
+}
+
+QDF_STATUS
+wma_pasn_peer_create(struct wlan_objmgr_psoc *psoc,
+		     struct qdf_mac_addr *peer_addr,
+		     uint8_t vdev_id)
+{
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+	target_resource_config *wlan_res_cfg;
+	struct wlan_objmgr_peer *obj_peer;
+	struct wma_target_req *wma_req;
+	struct peer_create_rsp_params *peer_create_rsp;
+	struct peer_create_params param;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	bool is_tgt_peer_conf_supported;
+
+	if (!wma) {
+		wma_err("wma_handle is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wlan_res_cfg = lmac_get_tgt_res_cfg(psoc);
+	if (!wlan_res_cfg) {
+		wma_err("psoc target res cfg is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (wma->interfaces[vdev_id].peer_count >=
+	    wlan_res_cfg->num_peers) {
+		wma_err("the peer count exceeds the limit %d",
+			wma->interfaces[vdev_id].peer_count);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (qdf_is_macaddr_group(peer_addr) ||
+	    qdf_is_macaddr_zero(peer_addr)) {
+		wma_err("Invalid peer address received reject it");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	wma_acquire_wakelock(&wma->wmi_cmd_rsp_wake_lock,
+			     WMA_PEER_CREATE_RESPONSE_TIMEOUT);
+	/*
+	 * The peer object should be created before sending the WMI peer
+	 * create command to firmware.
+	 */
+	obj_peer = wma_create_objmgr_peer(wma, vdev_id, peer_addr->bytes,
+					  WMI_PEER_TYPE_PASN);
+	if (!obj_peer) {
+		wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	param.peer_addr = peer_addr->bytes;
+	param.peer_type = WMI_PEER_TYPE_PASN;
+	param.vdev_id = vdev_id;
+	if (wmi_unified_peer_create_send(wma->wmi_handle,
+					 &param) != QDF_STATUS_SUCCESS) {
+		wma_err("Unable to create peer in Target");
+		wlan_objmgr_peer_obj_delete(obj_peer);
+		wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
+
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/*
+	 * If fw doesn't advertise peer create confirm event support,
+	 * use the legacy peer create API
+	 */
+	is_tgt_peer_conf_supported =
+		wlan_psoc_nif_fw_ext_cap_get(wma->psoc,
+					     WLAN_SOC_F_PEER_CREATE_RESP);
+	if (!is_tgt_peer_conf_supported) {
+		wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	peer_create_rsp = qdf_mem_malloc(sizeof(*peer_create_rsp));
+	if (!peer_create_rsp) {
+		wlan_objmgr_peer_obj_delete(obj_peer);
+		wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	qdf_mem_copy(peer_create_rsp->peer_mac.bytes, peer_addr->bytes,
+		     QDF_MAC_ADDR_SIZE);
+	wma_req = wma_fill_hold_req(wma, vdev_id, WMA_PEER_CREATE_REQ,
+				    WMA_PASN_PEER_CREATE_RESPONSE,
+				    peer_create_rsp,
+				    WMA_PEER_CREATE_RESPONSE_TIMEOUT);
+	if (!wma_req) {
+		wma_err("vdev:%d failed to fill peer create req", vdev_id);
+		wma_remove_req(wma, vdev_id, WMA_PASN_PEER_CREATE_RESPONSE,
+			       peer_addr);
+		wma_pasn_peer_remove(psoc, peer_addr, vdev_id, false);
+		wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
+		qdf_mem_free(peer_create_rsp);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	wma_debug("Created ranging peer peer_addr " QDF_MAC_ADDR_FMT " vdev_id %d",
+		  QDF_MAC_ADDR_REF(peer_addr->bytes), vdev_id);
+
+	return status;
+}
+
+QDF_STATUS
+wma_pasn_handle_peer_create_conf(tp_wma_handle wma,
+				 struct qdf_mac_addr *peer_mac,
+				 QDF_STATUS status, uint8_t vdev_id)
+{
+	struct wlan_lmac_if_wifi_pos_rx_ops *rx_ops;
+
+	if (status)
+		wma_pasn_peer_remove(wma->psoc, peer_mac, vdev_id,
+				     QDF_IS_STATUS_ERROR(status));
+
+	rx_ops = wifi_pos_get_rx_ops(wma->psoc);
+	if (!rx_ops || !rx_ops->wifi_pos_ranging_peer_create_rsp_cb) {
+		wma_err("%s is null",
+			!rx_ops ? "rx_ops" : "rx_ops->ranging_peer_cb");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	rx_ops->wifi_pos_ranging_peer_create_rsp_cb(wma->psoc, vdev_id,
+						    peer_mac, status);
+
+	return QDF_STATUS_SUCCESS;
+}