xref: /wlan-dirver/qca-wifi-host-cmn/umac/wifi_pos/src/wifi_pos_pasn_api.c (revision 901120c066e139c7f8a2c8e4820561fdd83c67ef)
1 /*
2  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 /**
17  * DOC: wifi_pos_pasn_api.c
18  * This file defines the 11az PASN authentication related APIs for wifi_pos
19  * component.
20  */
21 
22 #include <wlan_lmac_if_def.h>
23 #include "wifi_pos_api.h"
24 #include "wifi_pos_pasn_api.h"
25 #include "wifi_pos_utils_i.h"
26 #include "wifi_pos_main_i.h"
27 #include "os_if_wifi_pos.h"
28 #include "os_if_wifi_pos_utils.h"
29 #include "target_if_wifi_pos.h"
30 #include "target_if_wifi_pos_rx_ops.h"
31 #include "wlan_objmgr_cmn.h"
32 #include "wlan_objmgr_global_obj.h"
33 #include "wlan_objmgr_psoc_obj.h"
34 #include "wlan_objmgr_peer_obj.h"
35 #include "wlan_lmac_if_def.h"
36 #include "wlan_vdev_mgr_tgt_if_tx_api.h"
37 
38 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT)
39 uint8_t wifi_pos_get_pasn_peer_count(struct wlan_objmgr_vdev *vdev)
40 {
41 	struct wifi_pos_vdev_priv_obj *vdev_pos_obj;
42 
43 	vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev);
44 	if (!vdev_pos_obj) {
45 		wifi_pos_err("Wifi pos vdev priv obj is null");
46 		return 0;
47 	}
48 
49 	return vdev_pos_obj->num_pasn_peers;
50 }
51 
52 void wifi_pos_update_pasn_peer_count(struct wlan_objmgr_vdev *vdev,
53 				     bool is_increment)
54 {
55 	struct wifi_pos_vdev_priv_obj *vdev_pos_obj;
56 
57 	vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev);
58 	if (!vdev_pos_obj) {
59 		wifi_pos_err("Wifi pos vdev priv obj is null");
60 		return;
61 	}
62 
63 	if (is_increment)
64 		vdev_pos_obj->num_pasn_peers++;
65 	else
66 		vdev_pos_obj->num_pasn_peers--;
67 }
68 #endif
69 
70 void wifi_pos_set_11az_failed_peers(struct wlan_objmgr_vdev *vdev,
71 				    struct qdf_mac_addr *mac_addr)
72 {
73 	struct wifi_pos_vdev_priv_obj *vdev_pos_obj;
74 	struct wifi_pos_11az_context *pasn_context;
75 	uint8_t i;
76 
77 	vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev);
78 	if (!vdev_pos_obj) {
79 		wifi_pos_err("Wifi pos vdev priv obj is null");
80 		return;
81 	}
82 
83 	pasn_context = &vdev_pos_obj->pasn_context;
84 	if (!pasn_context->num_failed_peers)
85 		goto add_failed_peer;
86 
87 	for (i = 0; i < WLAN_MAX_11AZ_PEERS; i++) {
88 		if (qdf_is_macaddr_equal(mac_addr,
89 					 &pasn_context->failed_peer_list[i])) {
90 			wifi_pos_debug("Peer: " QDF_MAC_ADDR_FMT " already exists in failed list",
91 				       QDF_MAC_ADDR_REF(mac_addr->bytes));
92 			return;
93 		}
94 	}
95 
96 add_failed_peer:
97 	for (i = 0; i < WLAN_MAX_11AZ_PEERS; i++) {
98 		if (qdf_is_macaddr_broadcast(
99 					&pasn_context->failed_peer_list[i])) {
100 			qdf_copy_macaddr(&pasn_context->failed_peer_list[i],
101 					 mac_addr);
102 			pasn_context->num_failed_peers++;
103 			wifi_pos_debug("Added failed peer: " QDF_MAC_ADDR_FMT " at idx[%d]",
104 				       QDF_MAC_ADDR_REF(mac_addr->bytes), i);
105 
106 			return;
107 		}
108 	}
109 
110 	wifi_pos_debug("Not able to set failed peer");
111 }
112 
113 void wifi_pos_add_peer_to_list(struct wlan_objmgr_vdev *vdev,
114 			       struct wlan_pasn_request *req,
115 			       bool is_peer_create_required)
116 {
117 	struct wifi_pos_vdev_priv_obj *vdev_pos_obj;
118 	struct wifi_pos_11az_context *pasn_context;
119 	struct wlan_pasn_request *secure_list, *unsecure_list, *dst_entry;
120 	uint8_t i;
121 
122 	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE)
123 		return;
124 
125 	vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev);
126 	if (!vdev_pos_obj) {
127 		wifi_pos_err("Wifi pos vdev priv obj is null");
128 		return;
129 	}
130 
131 	pasn_context = &vdev_pos_obj->pasn_context;
132 	secure_list = pasn_context->secure_peer_list;
133 	unsecure_list = pasn_context->unsecure_peer_list;
134 
135 	/* Find the 1st empty slot and copy the entry to peer list */
136 	for (i = 0; i < WLAN_MAX_11AZ_PEERS; i++) {
137 		if (req->peer_type == WLAN_WIFI_POS_PASN_SECURE_PEER)
138 			dst_entry = &secure_list[i];
139 		else
140 			dst_entry = &unsecure_list[i];
141 
142 		/* Current slot is not empty */
143 		if (!qdf_is_macaddr_broadcast(&dst_entry->peer_mac))
144 			continue;
145 
146 		*dst_entry = *req;
147 		if (is_peer_create_required)
148 			pasn_context->num_pending_peer_creation++;
149 
150 		if (req->peer_type == WLAN_WIFI_POS_PASN_SECURE_PEER)
151 			pasn_context->num_secure_peers++;
152 		else
153 			pasn_context->num_unsecure_peers++;
154 
155 		wifi_pos_debug("Added %s peer: " QDF_MAC_ADDR_FMT " at idx[%d]",
156 			       (req->peer_type == WLAN_WIFI_POS_PASN_SECURE_PEER) ? "secure" : "unsecure",
157 			       QDF_MAC_ADDR_REF(dst_entry->peer_mac.bytes), i);
158 
159 		break;
160 	}
161 }
162 
163 /**
164  * wifi_pos_move_peers_to_fail_list  - Move the peers in secure/unsecure list
165  * to failed peer list
166  * @vdev: Vdev pointer
167  * @peer_mac: Peer mac address
168  * @peer_type: Secure or unsecure PASN peer
169  *
170  * Return: None
171  */
172 static
173 void wifi_pos_move_peers_to_fail_list(struct wlan_objmgr_vdev *vdev,
174 				      struct qdf_mac_addr *peer_mac,
175 				      enum wifi_pos_pasn_peer_type peer_type)
176 {
177 	uint8_t i;
178 	struct wifi_pos_vdev_priv_obj *vdev_pos_obj;
179 	struct wifi_pos_11az_context *pasn_context;
180 	struct wlan_pasn_request *secure_list, *unsecure_list, *list = NULL;
181 	struct qdf_mac_addr entry_to_copy;
182 
183 	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE)
184 		return;
185 
186 	vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev);
187 	if (!vdev_pos_obj) {
188 		wifi_pos_err("Wifi pos vdev priv obj is null");
189 		return;
190 	}
191 
192 	pasn_context = &vdev_pos_obj->pasn_context;
193 
194 	/*
195 	 * Broadcast mac address will be sent by caller when initiate
196 	 * external auth fails and to move the entire list to failed
197 	 * peers list
198 	 */
199 	if (qdf_is_macaddr_broadcast(peer_mac)) {
200 		/* Clear the entire list and move it to failed peers list */
201 		if (peer_type == WLAN_WIFI_POS_PASN_SECURE_PEER)
202 			list = pasn_context->secure_peer_list;
203 		else if (peer_type == WLAN_WIFI_POS_PASN_UNSECURE_PEER)
204 			list = pasn_context->unsecure_peer_list;
205 
206 		if (!list) {
207 			wifi_pos_err("No Valid list exists");
208 			return;
209 		}
210 
211 		for (i = 0; i < WLAN_MAX_11AZ_PEERS; i++) {
212 			/*
213 			 * if valid entry exist in the list, set that mac
214 			 * address to failed list and clear that mac from the
215 			 * secure/unsecure list
216 			 */
217 			if (!qdf_is_macaddr_broadcast(&list[i].peer_mac)) {
218 				wifi_pos_set_11az_failed_peers(
219 						vdev, &list[i].peer_mac);
220 				qdf_set_macaddr_broadcast(&list[i].peer_mac);
221 			}
222 		}
223 
224 		return;
225 	}
226 
227 	secure_list = pasn_context->secure_peer_list;
228 	unsecure_list = pasn_context->unsecure_peer_list;
229 	/*
230 	 * This condition is hit when peer create confirm for a pasn
231 	 * peer is received with failure status
232 	 */
233 	for (i = 0; i < WLAN_MAX_11AZ_PEERS; i++) {
234 		/*
235 		 * Clear the individual entry that exist for the given
236 		 * mac address in secure/unsecure list
237 		 */
238 		if (qdf_is_macaddr_equal(peer_mac, &secure_list[i].peer_mac)) {
239 			entry_to_copy = secure_list[i].peer_mac;
240 			qdf_set_macaddr_broadcast(&secure_list[i].peer_mac);
241 			pasn_context->num_secure_peers--;
242 		} else if (qdf_is_macaddr_equal(peer_mac,
243 			   &unsecure_list[i].peer_mac)) {
244 			entry_to_copy = unsecure_list[i].peer_mac;
245 			qdf_set_macaddr_broadcast(&unsecure_list[i].peer_mac);
246 			pasn_context->num_unsecure_peers--;
247 		} else {
248 			continue;
249 		}
250 
251 		wifi_pos_set_11az_failed_peers(vdev, &entry_to_copy);
252 		break;
253 	}
254 }
255 
256 static QDF_STATUS
257 wifi_pos_request_external_pasn_auth(struct wlan_objmgr_psoc *psoc,
258 				    struct wlan_objmgr_vdev *vdev,
259 				    struct wlan_pasn_request *peer_list,
260 				    uint8_t num_peers)
261 {
262 	struct wifi_pos_vdev_priv_obj *vdev_pos_obj;
263 	struct wifi_pos_osif_ops *osif_cb;
264 	QDF_STATUS status;
265 
266 	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE)
267 		return QDF_STATUS_E_INVAL;
268 
269 	osif_cb = wifi_pos_get_osif_callbacks();
270 	if (!osif_cb || !osif_cb->osif_initiate_pasn_cb) {
271 		wifi_pos_err("OSIF %s cb is NULL",
272 			     !osif_cb ? "" : "PASN");
273 		return QDF_STATUS_E_FAILURE;
274 	}
275 
276 	vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev);
277 	if (!vdev_pos_obj) {
278 		wifi_pos_err("Wifi pos vdev priv obj is null");
279 		return QDF_STATUS_E_FAILURE;
280 	}
281 
282 	status = osif_cb->osif_initiate_pasn_cb(vdev, peer_list,
283 						num_peers, true);
284 	if (QDF_IS_STATUS_ERROR(status))
285 		wifi_pos_err("Initiate PASN auth failed");
286 
287 	return status;
288 }
289 
290 static QDF_STATUS
291 wifi_pos_request_flush_pasn_keys(struct wlan_objmgr_psoc *psoc,
292 				 struct wlan_objmgr_vdev *vdev,
293 				 struct wlan_pasn_request *peer_list,
294 				 uint8_t num_peers)
295 {
296 	struct wifi_pos_vdev_priv_obj *vdev_pos_obj;
297 	struct wifi_pos_osif_ops *osif_cb;
298 	QDF_STATUS status;
299 
300 	osif_cb = wifi_pos_get_osif_callbacks();
301 	if (!osif_cb || !osif_cb->osif_initiate_pasn_cb) {
302 		wifi_pos_err("OSIF %s cb is NULL",
303 			     !osif_cb ? "" : "PASN");
304 		return QDF_STATUS_E_FAILURE;
305 	}
306 
307 	vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev);
308 	if (!vdev_pos_obj) {
309 		wifi_pos_err("Wifi pos vdev priv obj is null");
310 		return QDF_STATUS_E_FAILURE;
311 	}
312 
313 	status = osif_cb->osif_initiate_pasn_cb(vdev, peer_list, num_peers,
314 						false);
315 
316 	return status;
317 }
318 
319 static QDF_STATUS
320 wifi_pos_check_and_initiate_pasn_authentication(struct wlan_objmgr_psoc *psoc,
321 						struct wlan_objmgr_vdev *vdev,
322 						struct wifi_pos_11az_context *pasn_ctx)
323 {
324 	struct qdf_mac_addr bcast_mac = QDF_MAC_ADDR_BCAST_INIT;
325 	QDF_STATUS status;
326 
327 	if (pasn_ctx->num_pending_peer_creation ||
328 	    !pasn_ctx->num_secure_peers)
329 		return QDF_STATUS_SUCCESS;
330 
331 	status = wifi_pos_request_external_pasn_auth(psoc, vdev,
332 						     pasn_ctx->secure_peer_list,
333 						     pasn_ctx->num_secure_peers);
334 	if (QDF_IS_STATUS_ERROR(status)) {
335 		wifi_pos_err("Initiate Pasn Authentication failed");
336 		wifi_pos_move_peers_to_fail_list(vdev, &bcast_mac,
337 						 WLAN_WIFI_POS_PASN_SECURE_PEER);
338 		/* TODO send PASN_STATUS cmd from here */
339 	}
340 
341 	return status;
342 }
343 
344 QDF_STATUS wifi_pos_handle_ranging_peer_create(struct wlan_objmgr_psoc *psoc,
345 					       struct wlan_pasn_request *req,
346 					       uint8_t vdev_id,
347 					       uint8_t total_entries)
348 {
349 	struct wifi_pos_legacy_ops *legacy_cb;
350 	struct wlan_objmgr_peer *peer;
351 	struct wlan_objmgr_vdev *vdev;
352 	struct wifi_pos_vdev_priv_obj *vdev_pos_obj;
353 	struct wifi_pos_11az_context *pasn_context;
354 	QDF_STATUS status = QDF_STATUS_SUCCESS;
355 	uint8_t i;
356 
357 	legacy_cb = wifi_pos_get_legacy_ops();
358 	if (!legacy_cb || !legacy_cb->pasn_peer_create_cb) {
359 		wifi_pos_err("legacy callbacks is not registered");
360 		return QDF_STATUS_E_FAILURE;
361 	}
362 
363 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
364 						    WLAN_WIFI_POS_CORE_ID);
365 	if (!vdev) {
366 		wifi_pos_err("Vdev object is null");
367 		return QDF_STATUS_E_FAILURE;
368 	}
369 
370 	wifi_pos_debug("PASN peer create request received. Num peers:%d",
371 		       total_entries);
372 	for (i = 0; i < total_entries; i++) {
373 		peer = wlan_objmgr_get_peer_by_mac(psoc, req[i].peer_mac.bytes,
374 						   WLAN_WIFI_POS_CORE_ID);
375 		/*
376 		 * If already PASN peer is found, then this is a request to
377 		 * initiate PASN authentication alone and not to send
378 		 * peer create to fw
379 		 */
380 		if (peer &&
381 		    (wlan_peer_get_peer_type(peer) == WLAN_PEER_RTT_PASN)) {
382 			wifi_pos_debug("PASN Peer: " QDF_MAC_ADDR_FMT "already exists",
383 				       QDF_MAC_ADDR_REF(req[i].peer_mac.bytes));
384 			wifi_pos_add_peer_to_list(vdev, &req[i], false);
385 			wlan_objmgr_peer_release_ref(peer,
386 						     WLAN_WIFI_POS_CORE_ID);
387 			continue;
388 		} else if (peer) {
389 			/*
390 			 * If a peer with given mac address already exists which
391 			 * is not a PASN peer, then move this peer to failed
392 			 * list
393 			 */
394 			wifi_pos_debug("Peer: " QDF_MAC_ADDR_FMT "of type:%d already exist",
395 				       QDF_MAC_ADDR_REF(req[i].peer_mac.bytes),
396 				       wlan_peer_get_peer_type(peer));
397 			wifi_pos_set_11az_failed_peers(vdev, &req[i].peer_mac);
398 			wlan_objmgr_peer_release_ref(peer,
399 						     WLAN_WIFI_POS_CORE_ID);
400 			continue;
401 		}
402 
403 		status = legacy_cb->pasn_peer_create_cb(psoc, &req[i].peer_mac,
404 							vdev_id);
405 		if (QDF_IS_STATUS_ERROR(status)) {
406 			wifi_pos_set_11az_failed_peers(vdev, &req[i].peer_mac);
407 			continue;
408 		}
409 
410 		wifi_pos_update_pasn_peer_count(vdev, true);
411 		if (req[i].is_ltf_keyseed_required) {
412 			peer = wlan_objmgr_get_peer_by_mac(psoc,
413 							   req[i].peer_mac.bytes,
414 							   WLAN_WIFI_POS_CORE_ID);
415 			if (peer) {
416 				wifi_pos_set_peer_ltf_keyseed_required(peer,
417 								       true);
418 				wlan_objmgr_peer_release_ref(peer,
419 							     WLAN_WIFI_POS_CORE_ID);
420 			}
421 		}
422 
423 		/* Track the peers only for I-STA mode */
424 		if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE)
425 			wifi_pos_add_peer_to_list(vdev, &req[i], true);
426 	}
427 
428 	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE)
429 		goto end;
430 
431 	vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev);
432 	if (!vdev_pos_obj) {
433 		wifi_pos_err("Wifi pos vdev priv obj is null");
434 		wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID);
435 		return QDF_STATUS_E_FAILURE;
436 	}
437 
438 	/*
439 	 * If peer already exists for all the entries provided in the request,
440 	 * then fw peer create will not be sent again. Just the secure list
441 	 * will be updated and num_pending_peer_creation will be 0.
442 	 * In this case initiate the PASN auth directly without waiting for
443 	 * peer create response.
444 	 */
445 	pasn_context = &vdev_pos_obj->pasn_context;
446 	status = wifi_pos_check_and_initiate_pasn_authentication(psoc, vdev,
447 								 pasn_context);
448 end:
449 	wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID);
450 
451 	return status;
452 }
453 
454 QDF_STATUS
455 wifi_pos_handle_ranging_peer_create_rsp(struct wlan_objmgr_psoc *psoc,
456 					uint8_t vdev_id,
457 					struct qdf_mac_addr *peer_mac,
458 					uint8_t peer_create_status)
459 {
460 	struct wlan_objmgr_vdev *vdev;
461 	struct wifi_pos_vdev_priv_obj *vdev_pos_obj;
462 	struct wifi_pos_11az_context *pasn_context;
463 	QDF_STATUS status = QDF_STATUS_SUCCESS;
464 
465 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
466 						    WLAN_WIFI_POS_CORE_ID);
467 	if (!vdev) {
468 		wifi_pos_err("Vdev object is null");
469 		return QDF_STATUS_E_FAILURE;
470 	}
471 
472 	vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev);
473 	if (!vdev_pos_obj) {
474 		wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID);
475 		wifi_pos_err("Wifi pos vdev priv obj is null");
476 		return QDF_STATUS_E_FAILURE;
477 	}
478 
479 	pasn_context = &vdev_pos_obj->pasn_context;
480 	if (pasn_context->num_pending_peer_creation)
481 		pasn_context->num_pending_peer_creation--;
482 
483 	wifi_pos_debug("Received peer create response for " QDF_MAC_ADDR_FMT " status:%d pending_count:%d",
484 		       QDF_MAC_ADDR_REF(peer_mac->bytes), peer_create_status,
485 		       pasn_context->num_pending_peer_creation);
486 
487 	if (peer_create_status) {
488 		wifi_pos_move_peers_to_fail_list(vdev, peer_mac,
489 						 WLAN_WIFI_POS_PASN_PEER_TYPE_MAX);
490 		wifi_pos_update_pasn_peer_count(vdev, false);
491 	}
492 
493 	status = wifi_pos_check_and_initiate_pasn_authentication(psoc, vdev,
494 								 pasn_context);
495 	wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID);
496 
497 	return QDF_STATUS_SUCCESS;
498 }
499 
500 QDF_STATUS wifi_pos_handle_ranging_peer_delete(struct wlan_objmgr_psoc *psoc,
501 					       struct wlan_pasn_request *req,
502 					       uint8_t vdev_id,
503 					       uint8_t total_entries)
504 {
505 	struct wifi_pos_legacy_ops *legacy_cb;
506 	struct wlan_objmgr_peer *peer;
507 	struct wlan_pasn_request *del_peer_list;
508 	struct wlan_objmgr_vdev *vdev;
509 	struct wifi_pos_vdev_priv_obj *vdev_pos_obj;
510 	bool no_fw_peer_delete;
511 	uint8_t peer_count = 0, i;
512 	QDF_STATUS status = QDF_STATUS_SUCCESS;
513 
514 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
515 						    WLAN_WIFI_POS_CORE_ID);
516 	if (!vdev) {
517 		wifi_pos_err("Vdev object is null");
518 		return QDF_STATUS_E_FAILURE;
519 	}
520 
521 	vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev);
522 	if (!vdev_pos_obj) {
523 		wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID);
524 		wifi_pos_err("Wifi pos vdev priv obj is null");
525 		return QDF_STATUS_E_FAILURE;
526 	}
527 
528 	if (vdev_pos_obj->is_delete_all_pasn_peer_in_progress) {
529 		wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID);
530 		wifi_pos_err("Vdev delete all peer in progress. Ignore individual peer delete");
531 		return QDF_STATUS_SUCCESS;
532 	}
533 	wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID);
534 
535 	legacy_cb = wifi_pos_get_legacy_ops();
536 	if (!legacy_cb || !legacy_cb->pasn_peer_delete_cb) {
537 		wifi_pos_err("legacy callback is not registered");
538 		return QDF_STATUS_E_FAILURE;
539 	}
540 
541 	del_peer_list = qdf_mem_malloc(sizeof(*del_peer_list) * total_entries);
542 	if (!del_peer_list)
543 		return QDF_STATUS_E_NOMEM;
544 
545 	for (i = 0; i < total_entries; i++) {
546 		peer = wlan_objmgr_get_peer_by_mac(psoc, req[i].peer_mac.bytes,
547 						   WLAN_WIFI_POS_CORE_ID);
548 		if (peer &&
549 		    (wlan_peer_get_peer_type(peer) == WLAN_PEER_RTT_PASN)) {
550 			no_fw_peer_delete = WIFI_POS_IS_PEER_ALREADY_DELETED(
551 							req[i].control_flags);
552 			wifi_pos_debug("Delete PASN Peer: " QDF_MAC_ADDR_FMT,
553 				       QDF_MAC_ADDR_REF(req[i].peer_mac.bytes));
554 
555 			del_peer_list[peer_count] = req[i];
556 			peer_count++;
557 
558 			status = legacy_cb->pasn_peer_delete_cb(
559 					psoc, &req[i].peer_mac,
560 					vdev_id, no_fw_peer_delete);
561 
562 			wlan_objmgr_peer_release_ref(peer,
563 						     WLAN_WIFI_POS_CORE_ID);
564 			continue;
565 		} else {
566 			wifi_pos_debug("PASN Peer: " QDF_MAC_ADDR_FMT "doesn't exist",
567 				       QDF_MAC_ADDR_REF(req[i].peer_mac.bytes));
568 			if (peer)
569 				wlan_objmgr_peer_release_ref(
570 						peer, WLAN_WIFI_POS_CORE_ID);
571 
572 			continue;
573 		}
574 	}
575 
576 	if (!peer_count) {
577 		wifi_pos_debug("No Peers to delete ");
578 		goto no_peer;
579 	}
580 
581 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
582 						    WLAN_WIFI_POS_CORE_ID);
583 	if (!vdev) {
584 		wifi_pos_err("Vdev object is null");
585 		qdf_mem_free(del_peer_list);
586 		return QDF_STATUS_E_FAILURE;
587 	}
588 
589 	status = wifi_pos_request_flush_pasn_keys(psoc, vdev,
590 						  del_peer_list,
591 						  peer_count);
592 	if (QDF_IS_STATUS_ERROR(status))
593 		wifi_pos_err("Failed to indicate peer deauth to userspace");
594 
595 	wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID);
596 
597 no_peer:
598 	qdf_mem_free(del_peer_list);
599 
600 	return status;
601 }
602 
603 QDF_STATUS
604 wifi_pos_send_pasn_auth_status(struct wlan_objmgr_psoc *psoc,
605 			       struct wlan_pasn_auth_status *data)
606 {
607 	struct wlan_lmac_if_wifi_pos_tx_ops *tx_ops;
608 	QDF_STATUS status;
609 	uint8_t vdev_id = data->vdev_id;
610 	struct wifi_pos_vdev_priv_obj *vdev_pos_obj;
611 	struct wifi_pos_11az_context *pasn_context;
612 	struct wlan_objmgr_vdev *vdev;
613 	uint8_t i, failed_peers_counter = 0, total_peers_to_fill = 0;
614 
615 	tx_ops = wifi_pos_get_tx_ops(psoc);
616 	if (!tx_ops || !tx_ops->send_rtt_pasn_auth_status) {
617 		wifi_pos_err("%s is null",
618 			     tx_ops ? "Tx_ops" : "send_auth_status cb");
619 		return QDF_STATUS_E_FAILURE;
620 	}
621 
622 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
623 						    WLAN_WIFI_POS_CORE_ID);
624 	if (!vdev) {
625 		wifi_pos_err("vdev obj is null");
626 		return QDF_STATUS_E_FAILURE;
627 	}
628 
629 	vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev);
630 	if (!vdev_pos_obj) {
631 		wifi_pos_err("Wifi pos vdev priv obj is null");
632 		wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID);
633 		return QDF_STATUS_E_FAILURE;
634 	}
635 
636 	pasn_context = &vdev_pos_obj->pasn_context;
637 	total_peers_to_fill = data->num_peers + pasn_context->num_failed_peers;
638 	for (i = data->num_peers; i < total_peers_to_fill; i++) {
639 		data->auth_status[i].peer_mac =
640 			pasn_context->failed_peer_list[failed_peers_counter];
641 		data->auth_status[i].status =
642 			WLAN_PASN_AUTH_STATUS_PEER_CREATE_FAILED;
643 
644 		failed_peers_counter++;
645 		if (failed_peers_counter >= pasn_context->num_failed_peers)
646 			break;
647 	}
648 
649 	status = tx_ops->send_rtt_pasn_auth_status(psoc, data);
650 	if (QDF_IS_STATUS_ERROR(status))
651 		wifi_pos_err("Failed to send PASN authentication status");
652 
653 	wifi_pos_init_11az_context(vdev_pos_obj);
654 	wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID);
655 
656 	return status;
657 }
658 
659 QDF_STATUS
660 wifi_pos_send_pasn_peer_deauth(struct wlan_objmgr_psoc *psoc,
661 			       struct qdf_mac_addr *peer_mac)
662 {
663 	struct wlan_lmac_if_wifi_pos_tx_ops *tx_ops;
664 	QDF_STATUS status;
665 
666 	tx_ops = wifi_pos_get_tx_ops(psoc);
667 	if (!tx_ops || !tx_ops->send_rtt_pasn_deauth) {
668 		wifi_pos_err("%s is null",
669 			     tx_ops ? "Tx_ops" : "send_pasn deauth cb");
670 		return QDF_STATUS_E_FAILURE;
671 	}
672 
673 	status = tx_ops->send_rtt_pasn_deauth(psoc, peer_mac);
674 
675 	return status;
676 }
677 
678 QDF_STATUS
679 wifi_pos_set_peer_ltf_keyseed_required(struct wlan_objmgr_peer *peer,
680 				       bool value)
681 {
682 	struct wlan_wifi_pos_peer_priv_obj *peer_priv;
683 
684 	peer_priv = wifi_pos_get_peer_private_object(peer);
685 	if (!peer_priv) {
686 		wifi_pos_err("peer private object is null");
687 		return QDF_STATUS_E_FAILURE;
688 	}
689 
690 	peer_priv->is_ltf_keyseed_required = value;
691 
692 	return QDF_STATUS_SUCCESS;
693 }
694 
695 bool wifi_pos_is_ltf_keyseed_required_for_peer(struct wlan_objmgr_peer *peer)
696 {
697 	struct wlan_wifi_pos_peer_priv_obj *peer_priv;
698 
699 	peer_priv = wifi_pos_get_peer_private_object(peer);
700 	if (!peer_priv) {
701 		wifi_pos_err("peer private object is null");
702 		return QDF_STATUS_E_FAILURE;
703 	}
704 
705 	return peer_priv->is_ltf_keyseed_required;
706 }
707 
708 static
709 void wifi_pos_delete_objmgr_ranging_peer(struct wlan_objmgr_psoc *psoc,
710 					 void *object, void *arg)
711 {
712 	struct wlan_objmgr_peer *peer = object;
713 	struct wlan_objmgr_vdev *vdev = arg;
714 	uint8_t vdev_id, peer_vdev_id;
715 	enum wlan_peer_type peer_type;
716 	QDF_STATUS status;
717 
718 	if (!peer) {
719 		wifi_pos_err("Peer is NULL");
720 		return;
721 	}
722 
723 	peer_type = wlan_peer_get_peer_type(peer);
724 	if (peer_type != WLAN_PEER_RTT_PASN)
725 		return;
726 
727 	if (!vdev) {
728 		wifi_pos_err("VDEV is NULL");
729 		return;
730 	}
731 
732 	vdev_id = wlan_vdev_get_id(vdev);
733 	peer_vdev_id = wlan_vdev_get_id(wlan_peer_get_vdev(peer));
734 	if (vdev_id != peer_vdev_id)
735 		return;
736 
737 	status = wlan_objmgr_peer_obj_delete(peer);
738 	if (QDF_IS_STATUS_ERROR(status))
739 		wifi_pos_err("Failed to delete peer");
740 
741 	wifi_pos_update_pasn_peer_count(vdev, false);
742 }
743 
744 QDF_STATUS
745 wifi_pos_cleanup_pasn_peers(struct wlan_objmgr_psoc *psoc,
746 			    struct wlan_objmgr_vdev *vdev)
747 {
748 	QDF_STATUS status;
749 
750 	wifi_pos_debug("Iterate and delete PASN peers");
751 	status = wlan_objmgr_iterate_obj_list(psoc, WLAN_PEER_OP,
752 					      wifi_pos_delete_objmgr_ranging_peer,
753 					      vdev, 0, WLAN_WIFI_POS_CORE_ID);
754 	if (QDF_IS_STATUS_ERROR(status))
755 		wifi_pos_err("Delete objmgr peers failed");
756 
757 	return status;
758 }
759 
760 QDF_STATUS
761 wifi_pos_vdev_delete_all_ranging_peers(struct wlan_objmgr_vdev *vdev)
762 {
763 	QDF_STATUS status;
764 	struct vdev_mlme_obj *vdev_mlme;
765 	struct wifi_pos_vdev_priv_obj *vdev_pos_obj;
766 	struct peer_delete_all_params param;
767 
768 	vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev);
769 	if (!vdev_pos_obj) {
770 		wifi_pos_err("Wifi pos vdev priv obj is null");
771 		return QDF_STATUS_E_FAILURE;
772 	}
773 
774 	if (!vdev_pos_obj->num_pasn_peers)
775 		return QDF_STATUS_SUCCESS;
776 
777 	vdev_pos_obj->is_delete_all_pasn_peer_in_progress = true;
778 
779 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
780 	if (!vdev_mlme) {
781 		wifi_pos_err(" VDEV MLME component object is NULL");
782 		return QDF_STATUS_E_FAILURE;
783 	}
784 
785 	param.vdev_id = wlan_vdev_get_id(vdev);
786 	param.peer_type_bitmap = BIT(WLAN_PEER_RTT_PASN);
787 
788 	status = tgt_vdev_mgr_peer_delete_all_send(vdev_mlme, &param);
789 	if (QDF_IS_STATUS_ERROR(status))
790 		wifi_pos_err("Send vdev delete all peers failed");
791 
792 	return status;
793 }
794 
795 QDF_STATUS
796 wifi_pos_vdev_delete_all_ranging_peers_rsp(struct wlan_objmgr_psoc *psoc,
797 					   uint8_t vdev_id)
798 {
799 	struct wifi_pos_legacy_ops *legacy_cb;
800 	struct wlan_objmgr_vdev *vdev;
801 	struct wifi_pos_vdev_priv_obj *vdev_pos_obj;
802 	QDF_STATUS status;
803 
804 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
805 						    WLAN_WIFI_POS_CORE_ID);
806 	if (!vdev) {
807 		wifi_pos_err(" VDEV is NULL");
808 		return QDF_STATUS_E_FAILURE;
809 	}
810 
811 	vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev);
812 	if (!vdev_pos_obj) {
813 		wifi_pos_err("Wifi pos vdev priv obj is null");
814 		wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID);
815 		return QDF_STATUS_E_FAILURE;
816 	}
817 
818 	status = wifi_pos_cleanup_pasn_peers(psoc, vdev);
819 	if (QDF_IS_STATUS_ERROR(status)) {
820 		wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID);
821 		return status;
822 	}
823 
824 	vdev_pos_obj->is_delete_all_pasn_peer_in_progress = false;
825 
826 	legacy_cb = wifi_pos_get_legacy_ops();
827 	if (!legacy_cb || !legacy_cb->pasn_vdev_delete_resume_cb) {
828 		wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID);
829 		wifi_pos_err("legacy callbacks is not registered");
830 		return QDF_STATUS_E_FAILURE;
831 	}
832 
833 	status = legacy_cb->pasn_vdev_delete_resume_cb(vdev);
834 	if (QDF_IS_STATUS_ERROR(status))
835 		wifi_pos_err("Delete all PASN peer failed");
836 
837 	wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID);
838 
839 	return status;
840 }
841 
842 bool wifi_pos_is_delete_all_peer_in_progress(struct wlan_objmgr_vdev *vdev)
843 {
844 	struct wifi_pos_vdev_priv_obj *vdev_pos_obj;
845 
846 	vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev);
847 	if (!vdev_pos_obj) {
848 		wifi_pos_err("Wifi pos vdev priv obj is null");
849 		return false;
850 	}
851 
852 	return vdev_pos_obj->is_delete_all_pasn_peer_in_progress;
853 }
854 
855 void wifi_pos_set_delete_all_peer_in_progress(struct wlan_objmgr_vdev *vdev,
856 					      bool flag)
857 {
858 	struct wifi_pos_vdev_priv_obj *vdev_pos_obj;
859 
860 	vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev);
861 	if (!vdev_pos_obj) {
862 		wifi_pos_err("Wifi pos vdev priv obj is null");
863 		return;
864 	}
865 
866 	vdev_pos_obj->is_delete_all_pasn_peer_in_progress = flag;
867 }
868