1 /*
2  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 /**
19  * DOC: define internal APIs related to the mlme TWT functionality
20  */
21 
22 #include "cfg_mlme_twt.h"
23 #include "cfg_ucfg_api.h"
24 #include "wlan_mlme_main.h"
25 #include "wlan_psoc_mlme_api.h"
26 #include "wlan_vdev_mlme_api.h"
27 #include "wlan_mlme_api.h"
28 #include "wlan_mlme_twt_api.h"
29 
mlme_is_max_twt_sessions_reached(struct wlan_objmgr_psoc * psoc,struct qdf_mac_addr * peer_mac,uint8_t dialog_id)30 bool mlme_is_max_twt_sessions_reached(struct wlan_objmgr_psoc *psoc,
31 				      struct qdf_mac_addr *peer_mac,
32 				      uint8_t dialog_id)
33 {
34 	struct peer_mlme_priv_obj *peer_priv;
35 	struct wlan_objmgr_peer *peer;
36 	uint8_t i;
37 	uint8_t num_twt_sessions = 0, max_twt_sessions;
38 
39 	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac->bytes,
40 					   WLAN_MLME_NB_ID);
41 	if (!peer) {
42 		mlme_legacy_err("Peer object not found "QDF_MAC_ADDR_FMT,
43 				QDF_MAC_ADDR_REF(peer_mac->bytes));
44 		return true;
45 	}
46 
47 	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
48 							  WLAN_UMAC_COMP_MLME);
49 	if (!peer_priv) {
50 		wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
51 		mlme_legacy_err("peer mlme component object is NULL");
52 		return true;
53 	}
54 
55 	max_twt_sessions = peer_priv->twt_ctx.num_twt_sessions;
56 	for (i = 0; i < max_twt_sessions; i++) {
57 		uint8_t existing_session_dialog_id =
58 				peer_priv->twt_ctx.session_info[i].dialog_id;
59 
60 		if (existing_session_dialog_id != TWT_ALL_SESSIONS_DIALOG_ID &&
61 		    existing_session_dialog_id != dialog_id)
62 			num_twt_sessions++;
63 	}
64 	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
65 
66 	mlme_legacy_debug("num_twt_sessions:%d max_twt_sessions:%d",
67 			  num_twt_sessions, max_twt_sessions);
68 	return num_twt_sessions == max_twt_sessions;
69 }
70 
mlme_is_twt_setup_in_progress(struct wlan_objmgr_psoc * psoc,struct qdf_mac_addr * peer_mac,uint8_t dialog_id)71 bool mlme_is_twt_setup_in_progress(struct wlan_objmgr_psoc *psoc,
72 				   struct qdf_mac_addr *peer_mac,
73 				   uint8_t dialog_id)
74 {
75 	struct peer_mlme_priv_obj *peer_priv;
76 	struct wlan_objmgr_peer *peer;
77 	uint8_t existing_session_dialog_id;
78 	uint8_t i;
79 
80 	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac->bytes,
81 					   WLAN_MLME_NB_ID);
82 	if (!peer) {
83 		mlme_legacy_err("Peer object not found "QDF_MAC_ADDR_FMT,
84 				QDF_MAC_ADDR_REF(peer_mac->bytes));
85 		return false;
86 	}
87 
88 	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
89 							  WLAN_UMAC_COMP_MLME);
90 	if (!peer_priv) {
91 		wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
92 		mlme_legacy_err("peer mlme component object is NULL");
93 		return false;
94 	}
95 
96 	for (i = 0; i < peer_priv->twt_ctx.num_twt_sessions; i++) {
97 		bool setup_done = peer_priv->twt_ctx.session_info[i].setup_done;
98 		existing_session_dialog_id =
99 			peer_priv->twt_ctx.session_info[i].dialog_id;
100 		if (existing_session_dialog_id == dialog_id &&
101 		    existing_session_dialog_id != TWT_ALL_SESSIONS_DIALOG_ID &&
102 		    !setup_done) {
103 			wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
104 			return true;
105 		}
106 	}
107 	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
108 
109 	return false;
110 }
111 
mlme_add_twt_session(struct wlan_objmgr_psoc * psoc,struct qdf_mac_addr * peer_mac,uint8_t dialog_id)112 void mlme_add_twt_session(struct wlan_objmgr_psoc *psoc,
113 			  struct qdf_mac_addr *peer_mac,
114 			  uint8_t dialog_id)
115 {
116 	struct peer_mlme_priv_obj *peer_priv;
117 	struct wlan_objmgr_peer *peer;
118 	uint8_t i;
119 
120 	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac->bytes,
121 					   WLAN_MLME_NB_ID);
122 	if (!peer) {
123 		mlme_legacy_err("Peer object not found "QDF_MAC_ADDR_FMT,
124 				QDF_MAC_ADDR_REF(peer_mac->bytes));
125 		return;
126 	}
127 
128 	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
129 							  WLAN_UMAC_COMP_MLME);
130 	if (!peer_priv) {
131 		wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
132 		mlme_legacy_err("peer mlme component object is NULL");
133 		return;
134 	}
135 
136 	for (i = 0; i < peer_priv->twt_ctx.num_twt_sessions; i++) {
137 		if (peer_priv->twt_ctx.session_info[i].dialog_id ==
138 		    TWT_ALL_SESSIONS_DIALOG_ID) {
139 			peer_priv->twt_ctx.session_info[i].dialog_id =
140 							dialog_id;
141 			break;
142 		}
143 	}
144 
145 	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
146 }
147 
mlme_set_twt_setup_done(struct wlan_objmgr_psoc * psoc,struct qdf_mac_addr * peer_mac,uint8_t dialog_id,bool is_set)148 void mlme_set_twt_setup_done(struct wlan_objmgr_psoc *psoc,
149 			     struct qdf_mac_addr *peer_mac,
150 			     uint8_t dialog_id, bool is_set)
151 {
152 	struct peer_mlme_priv_obj *peer_priv;
153 	struct wlan_objmgr_peer *peer;
154 	uint8_t i;
155 
156 	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac->bytes,
157 					   WLAN_MLME_NB_ID);
158 	if (!peer) {
159 		mlme_legacy_err("Peer object not found "QDF_MAC_ADDR_FMT,
160 				QDF_MAC_ADDR_REF(peer_mac->bytes));
161 		return;
162 	}
163 
164 	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
165 							  WLAN_UMAC_COMP_MLME);
166 	if (!peer_priv) {
167 		wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
168 		mlme_legacy_err(" peer mlme component object is NULL");
169 		return;
170 	}
171 
172 	for (i = 0; i < peer_priv->twt_ctx.num_twt_sessions; i++) {
173 		if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id) {
174 			peer_priv->twt_ctx.session_info[i].setup_done = is_set;
175 			mlme_legacy_debug("setup done:%d dialog:%d", is_set,
176 					  dialog_id);
177 			break;
178 		}
179 	}
180 
181 	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
182 }
183 
mlme_init_twt_context(struct wlan_objmgr_psoc * psoc,struct qdf_mac_addr * peer_mac,uint8_t dialog_id)184 QDF_STATUS mlme_init_twt_context(struct wlan_objmgr_psoc *psoc,
185 				 struct qdf_mac_addr *peer_mac,
186 				 uint8_t dialog_id)
187 {
188 	struct peer_mlme_priv_obj *peer_priv;
189 	struct wlan_objmgr_peer *peer;
190 	uint8_t i;
191 
192 	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac->bytes,
193 					   WLAN_MLME_NB_ID);
194 	if (!peer) {
195 		mlme_legacy_debug("Peer object not found "QDF_MAC_ADDR_FMT,
196 				  QDF_MAC_ADDR_REF(peer_mac->bytes));
197 		return QDF_STATUS_E_FAILURE;
198 	}
199 
200 	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
201 							  WLAN_UMAC_COMP_MLME);
202 	if (!peer_priv) {
203 		wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
204 		mlme_legacy_debug("peer mlme component object is NULL");
205 		return QDF_STATUS_E_FAILURE;
206 	}
207 
208 	peer_priv->twt_ctx.num_twt_sessions = WLAN_MAX_TWT_SESSIONS_PER_PEER;
209 	for (i = 0; i < peer_priv->twt_ctx.num_twt_sessions; i++) {
210 		if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id ||
211 		    dialog_id == TWT_ALL_SESSIONS_DIALOG_ID) {
212 			peer_priv->twt_ctx.session_info[i].setup_done = false;
213 			peer_priv->twt_ctx.session_info[i].dialog_id =
214 					TWT_ALL_SESSIONS_DIALOG_ID;
215 			mlme_set_twt_command_in_progress(
216 				psoc, peer_mac,
217 				peer_priv->twt_ctx.session_info[i].dialog_id,
218 				WLAN_TWT_NONE);
219 		}
220 	}
221 
222 	mlme_legacy_debug("init done");
223 
224 	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
225 
226 	return QDF_STATUS_SUCCESS;
227 }
228 
229 QDF_STATUS
mlme_init_all_peers_twt_context(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint8_t dialog_id)230 mlme_init_all_peers_twt_context(struct wlan_objmgr_psoc *psoc,
231 				uint8_t vdev_id,
232 				uint8_t dialog_id)
233 {
234 	qdf_list_t *peer_list;
235 	struct wlan_objmgr_peer *peer, *peer_next;
236 	struct wlan_objmgr_vdev *vdev;
237 	struct peer_mlme_priv_obj *peer_priv;
238 
239 	if (!psoc) {
240 		mlme_legacy_err("psoc is NULL, dialog_id: %d", dialog_id);
241 		return QDF_STATUS_E_NULL_VALUE;
242 	}
243 
244 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
245 						    WLAN_MLME_NB_ID);
246 	if (!vdev) {
247 		mlme_legacy_err("vdev is NULL, vdev_id: %d dialog_id: %d",
248 				vdev_id, dialog_id);
249 		return QDF_STATUS_E_NULL_VALUE;
250 	}
251 
252 	peer_list = &vdev->vdev_objmgr.wlan_peer_list;
253 	if (!peer_list) {
254 		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
255 		mlme_legacy_err("Peer list for vdev obj is NULL");
256 		return QDF_STATUS_E_NULL_VALUE;
257 	}
258 
259         peer = wlan_vdev_peer_list_peek_active_head(vdev, peer_list,
260                                                     WLAN_MLME_NB_ID);
261 	while (peer) {
262 		peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
263 							  WLAN_UMAC_COMP_MLME);
264 		if (peer_priv) {
265 			uint8_t i = 0;
266 			uint8_t num_twt_sessions =
267 					WLAN_MAX_TWT_SESSIONS_PER_PEER;
268 
269 			peer_priv->twt_ctx.num_twt_sessions =
270 					num_twt_sessions;
271 			for (i = 0; i < num_twt_sessions; i++) {
272 				uint8_t existing_dialog_id =
273 				peer_priv->twt_ctx.session_info[i].dialog_id;
274 
275 				if (existing_dialog_id == dialog_id ||
276 				    dialog_id == TWT_ALL_SESSIONS_DIALOG_ID) {
277 					peer_priv->twt_ctx.session_info[i].setup_done = false;
278 					peer_priv->twt_ctx.session_info[i].dialog_id =
279 							TWT_ALL_SESSIONS_DIALOG_ID;
280 				}
281 			}
282 		}
283 
284 		peer_next =
285 			wlan_peer_get_next_active_peer_of_vdev(vdev,
286 							       peer_list,
287 							       peer,
288 							       WLAN_MLME_NB_ID);
289 
290 		wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
291 		peer = peer_next;
292         }
293 
294 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
295 	mlme_legacy_debug("init done");
296         return QDF_STATUS_SUCCESS;
297 }
298 
299 
mlme_is_twt_setup_done(struct wlan_objmgr_psoc * psoc,struct qdf_mac_addr * peer_mac,uint8_t dialog_id)300 bool mlme_is_twt_setup_done(struct wlan_objmgr_psoc *psoc,
301 			    struct qdf_mac_addr *peer_mac, uint8_t dialog_id)
302 {
303 	struct peer_mlme_priv_obj *peer_priv;
304 	struct wlan_objmgr_peer *peer;
305 	bool is_setup_done = false;
306 	uint8_t i;
307 
308 	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac->bytes,
309 					   WLAN_MLME_NB_ID);
310 	if (!peer) {
311 		mlme_legacy_err("Peer object not found "QDF_MAC_ADDR_FMT,
312 				QDF_MAC_ADDR_REF(peer_mac->bytes));
313 		return false;
314 	}
315 
316 	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
317 							  WLAN_UMAC_COMP_MLME);
318 	if (!peer_priv) {
319 		wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
320 		mlme_legacy_err("peer mlme component object is NULL");
321 		return false;
322 	}
323 
324 	for (i = 0; i < peer_priv->twt_ctx.num_twt_sessions; i++) {
325 		if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id ||
326 		    dialog_id == TWT_ALL_SESSIONS_DIALOG_ID) {
327 			is_setup_done =
328 				peer_priv->twt_ctx.session_info[i].setup_done;
329 
330 			if (dialog_id != TWT_ALL_SESSIONS_DIALOG_ID ||
331 			    is_setup_done)
332 				break;
333 		}
334 	}
335 
336 	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
337 
338 	return is_setup_done;
339 }
340 
mlme_twt_set_wait_for_notify(struct wlan_objmgr_psoc * psoc,uint32_t vdev_id,bool is_set)341 void mlme_twt_set_wait_for_notify(struct wlan_objmgr_psoc *psoc,
342 				  uint32_t vdev_id, bool is_set)
343 {
344 	struct wlan_objmgr_vdev *vdev;
345 	struct mlme_legacy_priv *mlme_priv;
346 
347 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
348 						    WLAN_MLME_NB_ID);
349 	if (!vdev) {
350 		mlme_legacy_err("vdev object not found");
351 		return;
352 	}
353 
354 	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
355 	if (!mlme_priv) {
356 		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
357 		mlme_legacy_err("vdev legacy private object is NULL");
358 		return;
359 	}
360 
361 	mlme_priv->twt_wait_for_notify = is_set;
362 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
363 }
364 
mlme_set_twt_session_state(struct wlan_objmgr_psoc * psoc,struct qdf_mac_addr * peer_mac,uint8_t dialog_id,enum wlan_twt_session_state state)365 void mlme_set_twt_session_state(struct wlan_objmgr_psoc *psoc,
366 				struct qdf_mac_addr *peer_mac,
367 				uint8_t dialog_id,
368 				enum wlan_twt_session_state state)
369 {
370 	struct wlan_objmgr_peer *peer;
371 	struct peer_mlme_priv_obj *peer_priv;
372 	uint8_t i;
373 
374 	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac->bytes,
375 					   WLAN_MLME_NB_ID);
376 	if (!peer) {
377 		mlme_legacy_err("Peer object not found "QDF_MAC_ADDR_FMT,
378 				QDF_MAC_ADDR_REF(peer_mac->bytes));
379 		return;
380 	}
381 
382 	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
383 							  WLAN_UMAC_COMP_MLME);
384 	if (!peer_priv) {
385 		wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
386 		mlme_err(" peer mlme component object is NULL");
387 		return;
388 	}
389 
390 	mlme_debug("set_state:%d for dialog_id:%d", state, dialog_id);
391 	for (i = 0; i < peer_priv->twt_ctx.num_twt_sessions; i++) {
392 		if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id ||
393 		    dialog_id == TWT_ALL_SESSIONS_DIALOG_ID) {
394 			peer_priv->twt_ctx.session_info[i].state = state;
395 			break;
396 		}
397 	}
398 
399 	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
400 }
401 
402 enum wlan_twt_session_state
mlme_get_twt_session_state(struct wlan_objmgr_psoc * psoc,struct qdf_mac_addr * peer_mac,uint8_t dialog_id)403 mlme_get_twt_session_state(struct wlan_objmgr_psoc *psoc,
404 			   struct qdf_mac_addr *peer_mac, uint8_t dialog_id)
405 {
406 	struct wlan_objmgr_peer *peer;
407 	struct peer_mlme_priv_obj *peer_priv;
408 	uint8_t i;
409 
410 	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac->bytes,
411 					   WLAN_MLME_NB_ID);
412 	if (!peer) {
413 		mlme_legacy_err("Peer object not found "QDF_MAC_ADDR_FMT,
414 				QDF_MAC_ADDR_REF(peer_mac->bytes));
415 		return WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED;
416 	}
417 
418 	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
419 							  WLAN_UMAC_COMP_MLME);
420 	if (!peer_priv) {
421 		wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
422 		mlme_legacy_err(" peer mlme object is NULL");
423 		return WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED;
424 	}
425 
426 	for (i = 0; i < peer_priv->twt_ctx.num_twt_sessions; i++) {
427 		if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id &&
428 		    dialog_id != TWT_ALL_SESSIONS_DIALOG_ID) {
429 			wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
430 			return peer_priv->twt_ctx.session_info[i].state;
431 		}
432 	}
433 
434 	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
435 
436 	return WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED;
437 }
438 
mlme_get_twt_peer_capabilities(struct wlan_objmgr_psoc * psoc,struct qdf_mac_addr * peer_mac)439 uint8_t mlme_get_twt_peer_capabilities(struct wlan_objmgr_psoc *psoc,
440 				       struct qdf_mac_addr *peer_mac)
441 {
442 	struct peer_mlme_priv_obj *peer_priv;
443 	struct wlan_objmgr_peer *peer;
444 
445 	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac->bytes,
446 					   WLAN_MLME_NB_ID);
447 	if (!peer) {
448 		mlme_legacy_err("Peer object not found "QDF_MAC_ADDR_FMT,
449 				QDF_MAC_ADDR_REF(peer_mac->bytes));
450 		return false;
451 	}
452 
453 	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
454 							  WLAN_UMAC_COMP_MLME);
455 	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
456 	if (!peer_priv) {
457 		mlme_legacy_err("peer mlme object is NULL");
458 		return 0;
459 	}
460 
461 	return peer_priv->twt_ctx.peer_capability;
462 }
463 
mlme_set_twt_peer_capabilities(struct wlan_objmgr_psoc * psoc,struct qdf_mac_addr * peer_mac,uint8_t caps)464 void mlme_set_twt_peer_capabilities(struct wlan_objmgr_psoc *psoc,
465 				    struct qdf_mac_addr *peer_mac,
466 				    uint8_t caps)
467 {
468 	struct wlan_objmgr_peer *peer;
469 	struct peer_mlme_priv_obj *peer_priv;
470 
471 	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac->bytes,
472 					   WLAN_MLME_NB_ID);
473 	if (!peer) {
474 		mlme_legacy_debug("Peer object not found "QDF_MAC_ADDR_FMT,
475 				  QDF_MAC_ADDR_REF(peer_mac->bytes));
476 		return;
477 	}
478 
479 	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
480 							  WLAN_UMAC_COMP_MLME);
481 	if (!peer_priv) {
482 		wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
483 		mlme_legacy_debug("peer mlme object is NULL");
484 		return;
485 	}
486 
487 	peer_priv->twt_ctx.peer_capability = caps;
488 	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
489 }
490 
mlme_is_twt_enabled(struct wlan_objmgr_psoc * psoc)491 bool mlme_is_twt_enabled(struct wlan_objmgr_psoc *psoc)
492 {
493 	struct wlan_mlme_psoc_ext_obj *mlme_obj;
494 
495 	mlme_obj = mlme_get_psoc_ext_obj(psoc);
496 	if (!mlme_obj)
497 		return cfg_default(CFG_ENABLE_TWT);
498 
499 	return mlme_obj->cfg.twt_cfg.is_twt_enabled;
500 }
501 
502 #if defined(WLAN_FEATURE_11AX) && defined(WLAN_SUPPORT_TWT)
mlme_is_flexible_twt_enabled(struct wlan_objmgr_psoc * psoc)503 bool mlme_is_flexible_twt_enabled(struct wlan_objmgr_psoc *psoc)
504 {
505 	struct wlan_mlme_psoc_ext_obj *mlme_obj;
506 
507 	mlme_obj = mlme_get_psoc_ext_obj(psoc);
508 	if (!mlme_obj)
509 		return false;
510 
511 	return mlme_obj->cfg.he_caps.dot11_he_cap.flex_twt_sched;
512 }
513 #endif
514 
515 QDF_STATUS
mlme_sap_set_twt_all_peers_cmd_in_progress(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint8_t dialog_id,enum wlan_twt_commands cmd)516 mlme_sap_set_twt_all_peers_cmd_in_progress(struct wlan_objmgr_psoc *psoc,
517 					   uint8_t vdev_id,
518 					   uint8_t dialog_id,
519 					   enum wlan_twt_commands cmd)
520 {
521 	qdf_list_t *peer_list;
522 	struct wlan_objmgr_peer *peer, *peer_next;
523 	struct wlan_objmgr_vdev *vdev;
524 	struct peer_mlme_priv_obj *peer_priv;
525 
526 	if (!psoc) {
527 		mlme_legacy_err("psoc is NULL, dialog_id: %d", dialog_id);
528 		return QDF_STATUS_E_NULL_VALUE;
529 	}
530 
531 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
532 						    WLAN_MLME_NB_ID);
533 	if (!vdev) {
534 		mlme_legacy_err("vdev is NULL, vdev_id: %d dialog_id: %d",
535 				vdev_id, dialog_id);
536 		return QDF_STATUS_E_NULL_VALUE;
537 	}
538 
539 	peer_list = &vdev->vdev_objmgr.wlan_peer_list;
540 	if (!peer_list) {
541 		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
542 		mlme_legacy_err("Peer list for vdev obj is NULL");
543 		return QDF_STATUS_E_NULL_VALUE;
544 	}
545 
546         peer = wlan_vdev_peer_list_peek_active_head(vdev, peer_list,
547                                                     WLAN_MLME_NB_ID);
548 	while (peer) {
549 		peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
550 							  WLAN_UMAC_COMP_MLME);
551 		if (peer_priv) {
552 			uint8_t i = 0;
553 			uint8_t num_twt_sessions =
554 				peer_priv->twt_ctx.num_twt_sessions;
555 
556 			for (i = 0; i < num_twt_sessions; i++) {
557 				uint8_t existing_dialog_id =
558 				peer_priv->twt_ctx.session_info[i].dialog_id;
559 
560 				if (existing_dialog_id == dialog_id ||
561 				    dialog_id == TWT_ALL_SESSIONS_DIALOG_ID) {
562 					peer_priv->twt_ctx.session_info[i].active_cmd = cmd;
563 
564 					if (dialog_id !=
565 					    TWT_ALL_SESSIONS_DIALOG_ID) {
566 						break;
567 					}
568 				}
569 			}
570 		}
571 
572 		peer_next =
573 			wlan_peer_get_next_active_peer_of_vdev(vdev,
574 							       peer_list,
575 							       peer,
576 							       WLAN_MLME_NB_ID);
577 
578 		wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
579 		peer = peer_next;
580         }
581 
582 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
583         return QDF_STATUS_SUCCESS;
584 }
585 
586 bool
mlme_twt_any_peer_cmd_in_progress(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint8_t dialog_id,enum wlan_twt_commands cmd)587 mlme_twt_any_peer_cmd_in_progress(struct wlan_objmgr_psoc *psoc,
588 				  uint8_t vdev_id,
589 				  uint8_t dialog_id,
590 				  enum wlan_twt_commands cmd)
591 {
592 	qdf_list_t *peer_list;
593 	struct wlan_objmgr_peer *peer, *peer_next;
594 	struct wlan_objmgr_vdev *vdev;
595 	struct peer_mlme_priv_obj *peer_priv;
596 	bool cmd_in_progress = false;
597 
598 	if (!psoc) {
599 		mlme_legacy_err("psoc is NULL, dialog_id: %d", dialog_id);
600 		return false;
601 	}
602 
603 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
604 						    WLAN_MLME_NB_ID);
605 	if (!vdev) {
606 		mlme_legacy_err("vdev is NULL, vdev_id: %d dialog_id: %d",
607 				vdev_id, dialog_id);
608 		return false;
609 	}
610 
611 	peer_list = &vdev->vdev_objmgr.wlan_peer_list;
612 	if (!peer_list) {
613 		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
614 		mlme_legacy_err("Peer list for vdev obj is NULL");
615 		return false;
616 	}
617 
618         peer = wlan_vdev_peer_list_peek_active_head(vdev, peer_list,
619                                                     WLAN_MLME_NB_ID);
620 	while (peer) {
621 		peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
622 							  WLAN_UMAC_COMP_MLME);
623 		if (peer_priv) {
624 			uint8_t i = 0;
625 			uint8_t num_twt_sessions =
626 				peer_priv->twt_ctx.num_twt_sessions;
627 
628 			for (i = 0; i < num_twt_sessions; i++) {
629 				enum wlan_twt_commands active_cmd;
630 				uint8_t existing_dialog_id;
631 
632 				active_cmd =
633 				 peer_priv->twt_ctx.session_info[i].active_cmd;
634 				existing_dialog_id =
635 				 peer_priv->twt_ctx.session_info[i].dialog_id;
636 
637 				if (existing_dialog_id == dialog_id ||
638 				    dialog_id == TWT_ALL_SESSIONS_DIALOG_ID) {
639 					cmd_in_progress = (active_cmd == cmd);
640 
641 					if (dialog_id !=
642 						TWT_ALL_SESSIONS_DIALOG_ID ||
643 					    cmd_in_progress) {
644 						wlan_objmgr_peer_release_ref(
645 							peer,
646 							WLAN_MLME_NB_ID);
647 						wlan_objmgr_vdev_release_ref(
648 							vdev,
649 							WLAN_MLME_NB_ID);
650 						return cmd_in_progress;
651 					}
652 				}
653 			}
654 		}
655 
656 		peer_next =
657 			wlan_peer_get_next_active_peer_of_vdev(vdev,
658 							       peer_list,
659 							       peer,
660 							       WLAN_MLME_NB_ID);
661 
662 		wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
663 		peer = peer_next;
664         }
665 
666 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
667 	return cmd_in_progress;
668 }
669 
mlme_sap_twt_peer_is_cmd_in_progress(struct wlan_objmgr_psoc * psoc,struct qdf_mac_addr * peer_mac,uint8_t dialog_id,enum wlan_twt_commands cmd)670 bool mlme_sap_twt_peer_is_cmd_in_progress(struct wlan_objmgr_psoc *psoc,
671 				     struct qdf_mac_addr *peer_mac,
672 				     uint8_t dialog_id,
673 				     enum wlan_twt_commands cmd)
674 {
675 	struct wlan_objmgr_peer *peer;
676 	struct peer_mlme_priv_obj *peer_priv;
677 	uint8_t i = 0;
678 	bool cmd_in_progress = false;
679 
680 	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac->bytes,
681 					   WLAN_MLME_NB_ID);
682 	if (!peer) {
683 		mlme_legacy_err("Peer object not found "QDF_MAC_ADDR_FMT,
684 				QDF_MAC_ADDR_REF(peer_mac->bytes));
685 		return false;
686 	}
687 
688 	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
689 							  WLAN_UMAC_COMP_MLME);
690 	if (!peer_priv) {
691 		wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
692 		mlme_legacy_err(" peer mlme component object is NULL");
693 		return false;
694 	}
695 
696 	for (i = 0; i < peer_priv->twt_ctx.num_twt_sessions; i++) {
697 		enum wlan_twt_commands active_cmd;
698 		uint8_t existing_dialog_id;
699 
700 		active_cmd =
701 			peer_priv->twt_ctx.session_info[i].active_cmd;
702 		existing_dialog_id =
703 			peer_priv->twt_ctx.session_info[i].dialog_id;
704 
705 		if (existing_dialog_id == dialog_id ||
706 		    dialog_id == TWT_ALL_SESSIONS_DIALOG_ID ||
707 		    existing_dialog_id == TWT_ALL_SESSIONS_DIALOG_ID) {
708 			cmd_in_progress = (active_cmd == cmd);
709 
710 			if (dialog_id != TWT_ALL_SESSIONS_DIALOG_ID ||
711 			    cmd_in_progress) {
712 				break;
713 			}
714 		}
715 	}
716 
717 	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
718 	return cmd_in_progress;
719 }
720 
mlme_set_twt_command_in_progress(struct wlan_objmgr_psoc * psoc,struct qdf_mac_addr * peer_mac,uint8_t dialog_id,enum wlan_twt_commands cmd)721 QDF_STATUS mlme_set_twt_command_in_progress(struct wlan_objmgr_psoc *psoc,
722 					    struct qdf_mac_addr *peer_mac,
723 					    uint8_t dialog_id,
724 					    enum wlan_twt_commands cmd)
725 {
726 	struct wlan_objmgr_peer *peer;
727 	struct peer_mlme_priv_obj *peer_priv;
728 	uint8_t i = 0;
729 
730 	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac->bytes,
731 					   WLAN_MLME_NB_ID);
732 	if (!peer) {
733 		mlme_legacy_err("Peer object not found "QDF_MAC_ADDR_FMT,
734 				QDF_MAC_ADDR_REF(peer_mac->bytes));
735 		return QDF_STATUS_E_FAILURE;
736 	}
737 
738 	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
739 							  WLAN_UMAC_COMP_MLME);
740 	if (!peer_priv) {
741 		wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
742 		mlme_legacy_err(" peer mlme component object is NULL");
743 		return QDF_STATUS_E_FAILURE;
744 	}
745 
746 	for (i = 0; i < peer_priv->twt_ctx.num_twt_sessions; i++) {
747 		if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id ||
748 		    dialog_id == TWT_ALL_SESSIONS_DIALOG_ID) {
749 			peer_priv->twt_ctx.session_info[i].active_cmd = cmd;
750 			if (dialog_id != TWT_ALL_SESSIONS_DIALOG_ID)
751 				break;
752 		}
753 	}
754 
755 	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
756 
757 	return QDF_STATUS_SUCCESS;
758 }
759 
mlme_is_twt_notify_in_progress(struct wlan_objmgr_psoc * psoc,uint32_t vdev_id)760 bool mlme_is_twt_notify_in_progress(struct wlan_objmgr_psoc *psoc,
761 				    uint32_t vdev_id)
762 {
763 	struct wlan_objmgr_vdev *vdev;
764 	struct mlme_legacy_priv *mlme_priv;
765 	bool is_twt_notify_in_progress;
766 
767 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
768 						    WLAN_MLME_NB_ID);
769 
770 	if (!vdev) {
771 		mlme_legacy_err("vdev object not found");
772 		return false;
773 	}
774 
775 	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
776 	if (!mlme_priv) {
777 		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
778 		mlme_legacy_err("vdev legacy private object is NULL");
779 		return false;
780 	}
781 
782 	is_twt_notify_in_progress = mlme_priv->twt_wait_for_notify;
783 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
784 
785 	return is_twt_notify_in_progress;
786 }
787 
mlme_twt_is_command_in_progress(struct wlan_objmgr_psoc * psoc,struct qdf_mac_addr * peer_mac,uint8_t dialog_id,enum wlan_twt_commands cmd,enum wlan_twt_commands * pactive_cmd)788 bool mlme_twt_is_command_in_progress(struct wlan_objmgr_psoc *psoc,
789 				     struct qdf_mac_addr *peer_mac,
790 				     uint8_t dialog_id,
791 				     enum wlan_twt_commands cmd,
792 				     enum wlan_twt_commands *pactive_cmd)
793 {
794 	struct wlan_objmgr_peer *peer;
795 	struct peer_mlme_priv_obj *peer_priv;
796 	enum wlan_twt_commands active_cmd;
797 	uint8_t i = 0;
798 	bool is_command_in_progress = false;
799 
800 	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac->bytes,
801 					   WLAN_MLME_NB_ID);
802 	if (!peer) {
803 		mlme_legacy_err("Peer object not found "QDF_MAC_ADDR_FMT,
804 				QDF_MAC_ADDR_REF(peer_mac->bytes));
805 		return false;
806 	}
807 
808 	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
809 							  WLAN_UMAC_COMP_MLME);
810 	if (!peer_priv) {
811 		wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
812 		mlme_legacy_err(" peer mlme component object is NULL");
813 		return false;
814 	}
815 
816 	for (i = 0; i < peer_priv->twt_ctx.num_twt_sessions; i++) {
817 		active_cmd = peer_priv->twt_ctx.session_info[i].active_cmd;
818 
819 		if (pactive_cmd)
820 			*pactive_cmd = active_cmd;
821 
822 		if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id ||
823 		    dialog_id == TWT_ALL_SESSIONS_DIALOG_ID) {
824 			if (cmd == WLAN_TWT_ANY) {
825 				is_command_in_progress =
826 					(active_cmd != WLAN_TWT_NONE);
827 
828 				if (dialog_id != TWT_ALL_SESSIONS_DIALOG_ID ||
829 				    is_command_in_progress)
830 					break;
831 			} else {
832 				is_command_in_progress = (active_cmd == cmd);
833 
834 				if (dialog_id != TWT_ALL_SESSIONS_DIALOG_ID ||
835 				    is_command_in_progress)
836 					break;
837 			}
838 		}
839 	}
840 
841 	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
842 
843 	return is_command_in_progress;
844 }
845 
mlme_is_24ghz_twt_enabled(struct wlan_objmgr_psoc * psoc)846 bool mlme_is_24ghz_twt_enabled(struct wlan_objmgr_psoc *psoc)
847 {
848 	struct wlan_mlme_psoc_ext_obj *mlme_obj;
849 
850 	mlme_obj = mlme_get_psoc_ext_obj(psoc);
851 	if (!mlme_obj)
852 		return cfg_default(CFG_ENABLE_TWT_24GHZ);
853 
854 	return mlme_obj->cfg.twt_cfg.enable_twt_24ghz;
855 }
856 
857 #if defined(WLAN_SUPPORT_TWT) && defined(WLAN_TWT_CONV_SUPPORTED)
mlme_is_twt_disable_info_frame(struct wlan_objmgr_psoc * psoc)858 bool mlme_is_twt_disable_info_frame(struct wlan_objmgr_psoc *psoc)
859 {
860 	struct wlan_mlme_psoc_ext_obj *mlme_obj;
861 
862 	mlme_obj = mlme_get_psoc_ext_obj(psoc);
863 	if (!mlme_obj)
864 		return cfg_default(CFG_DISABLE_TWT_INFO_FRAME);
865 
866 	return mlme_obj->cfg.twt_cfg.disable_twt_info_frame;
867 }
868 #endif
869