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