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