xref: /wlan-dirver/qca-wifi-host-cmn/umac/mlo_mgr/inc/wlan_mlo_mgr_sta.h (revision d0c05845839e5f2ba5a8dcebe0cd3e4cd4e8dfcf)
1 /*
2  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2022 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: contains MLO manager public file containing STA functionality
20  */
21 #ifndef _WLAN_MLO_MGR_STA_H_
22 #define _WLAN_MLO_MGR_STA_H_
23 
24 #include <wlan_cm_ucfg_api.h>
25 #include <wlan_objmgr_vdev_obj.h>
26 #include <wlan_mlo_mgr_cmn.h>
27 #ifdef WLAN_FEATURE_11BE_MLO
28 #include <wlan_mlo_mgr_public_structs.h>
29 
30 /**
31  * mlo_connect - Start the connection process
32  *
33  * @vdev: pointer to vdev
34  * @req: connection request
35  *
36  * Return: QDF_STATUS
37  */
38 QDF_STATUS mlo_connect(struct wlan_objmgr_vdev *vdev,
39 		       struct wlan_cm_connect_req *req);
40 
41 /**
42  * mlo_sta_link_connect_notify - Called by connection manager to notify the
43  * STA link connect is complete
44  *
45  * @vdev: pointer to vdev
46  * @mlo_ie: MLO information element
47  *
48  * Connection manager will notify the MLO manager when the link has started
49  * and MLO manager will start the subsequent connections, if necessary
50  *
51  * Return: none
52  */
53 void
54 mlo_sta_link_connect_notify(struct wlan_objmgr_vdev *vdev,
55 			    struct wlan_cm_connect_resp *rsp);
56 
57 /**
58  * mlo_disconnect - Start the disconnection process
59  *
60  * @vdev: pointer to vdev
61  * @source: source of the request (can be connect or disconnect request)
62  * @reason_code: reason for disconnect
63  * @bssid: BSSID
64  *
65  * Return: QDF_STATUS
66  */
67 QDF_STATUS mlo_disconnect(struct wlan_objmgr_vdev *vdev,
68 			  enum wlan_cm_source source,
69 			  enum wlan_reason_code reason_code,
70 			  struct qdf_mac_addr *bssid);
71 
72 /**
73  * mlo_sync_disconnect - Start the sync disconnection process
74  *
75  * @vdev: pointer to vdev
76  * @source: source of the request (can be connect or disconnect request)
77  * @reason_code: reason for disconnect
78  * @bssid: BSSID
79  *
80  * Return: QDF_STATUS
81  */
82 QDF_STATUS mlo_sync_disconnect(struct wlan_objmgr_vdev *vdev,
83 			       enum wlan_cm_source source,
84 			       enum wlan_reason_code reason_code,
85 			       struct qdf_mac_addr *bssid);
86 
87 /**
88  * mlo_sta_link_disconn_notify - Notifies that STA link disconnect completion
89  *
90  * @vdev: pointer to vdev
91  * @resp: disconnect resp
92  *
93  * Return: none
94  */
95 void mlo_sta_link_disconn_notify(struct wlan_objmgr_vdev *vdev,
96 				 struct wlan_cm_discon_rsp *resp);
97 
98 /**
99  * mlo_is_mld_sta - Check if MLD associated with the vdev is a station
100  *
101  * @vdev: pointer to vdev
102  *
103  * Return: true if MLD is a station, false otherwise
104  */
105 bool mlo_is_mld_sta(struct wlan_objmgr_vdev *vdev);
106 
107 /**
108  * ucfg_mlo_is_mld_disconnected - Check whether MLD is disconnected
109  *
110  * @vdev: pointer to vdev
111  *
112  * Return: true if mld is disconnected, false otherwise
113  */
114 bool ucfg_mlo_is_mld_disconnected(struct wlan_objmgr_vdev *vdev);
115 
116 #ifndef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
117 /**
118  * ucfg_mlo_is_mld_connected - Check whether MLD is connected
119  *
120  * @vdev: pointer to vdev
121  *
122  * Return: true if mld is connected, false otherwise
123  */
124 bool ucfg_mlo_is_mld_connected(struct wlan_objmgr_vdev *vdev);
125 
126 /**
127  * ucfg_mlo_mld_clear_mlo_cap - Clear MLO cap for all vdevs in MLD
128  *
129  * @vdev: pointer to vdev
130  *
131  * Return: None
132  */
133 void ucfg_mlo_mld_clear_mlo_cap(struct wlan_objmgr_vdev *vdev);
134 #endif
135 
136 /*
137  * ucfg_mlo_get_assoc_link_vdev - API to get assoc link vdev
138  *
139  * @mlo_dev_ctx: mlo dev ctx
140  *
141  * Return: MLD assoc link vdev
142  */
143 struct wlan_objmgr_vdev *
144 ucfg_mlo_get_assoc_link_vdev(struct wlan_objmgr_vdev *vdev);
145 
146 /*
147  * wlan_mlo_get_assoc_link_vdev - API to get assoc link vdev
148  *
149  * @mlo_dev_ctx: mlo dev ctx
150  *
151  * Return: MLD assoc link vdev
152  */
153 struct wlan_objmgr_vdev *
154 wlan_mlo_get_assoc_link_vdev(struct wlan_objmgr_vdev *vdev);
155 
156 /*
157  * mlo_update_connected_links_bmap: update connected links bitmap
158  *
159  * @mlo_dev_ctx: mlo dev context ptr
160  * @ml_partner_info: ml parnter info ptr
161  *
162  * Return: none
163  */
164 void
165 mlo_update_connected_links_bmap(struct wlan_mlo_dev_context *mlo_dev_ctx,
166 				struct mlo_partner_info ml_parnter_info);
167 
168 /*
169  * API to have operation on ml vdevs
170  */
171 typedef void (*mlo_vdev_op_handler)(struct wlan_objmgr_vdev *vdev,
172 				    void *arg);
173 
174 /*
175  * mlo_iterate_connected_vdev_list: Iterate on connected ML links
176  *
177  * @vdev: vdev object
178  * @handler: the handler will be called for each object in ML list
179  * @arg: argumet to be passed to handler
180  *
181  * Return: none
182  */
183 static inline
184 void mlo_iterate_connected_vdev_list(struct wlan_objmgr_vdev *vdev,
185 				     mlo_vdev_op_handler handler,
186 				     void *arg)
187 {
188 	struct wlan_mlo_dev_context *mlo_dev_ctx = vdev->mlo_dev_ctx;
189 	struct wlan_mlo_sta *sta_ctx = NULL;
190 	uint8_t i = 0;
191 
192 	if (!mlo_dev_ctx || !(wlan_vdev_mlme_is_mlo_vdev(vdev)))
193 		return;
194 
195 	sta_ctx = mlo_dev_ctx->sta_ctx;
196 	if (!sta_ctx)
197 		return;
198 
199 	for (i =  0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
200 		if (!mlo_dev_ctx->wlan_vdev_list[i])
201 			continue;
202 		if (qdf_test_bit(i, sta_ctx->wlan_connected_links)) {
203 			if (handler)
204 				handler(mlo_dev_ctx->wlan_vdev_list[i], arg);
205 		}
206 	}
207 }
208 
209 /*
210  * mlo_update_connect_req_links: update connect req links index
211  *
212  * @vdev: vdev object
213  * @value: set/clear the bit
214  *
215  * Return: none
216  */
217 static inline void
218 mlo_update_connect_req_links(struct wlan_objmgr_vdev *vdev, uint8_t value)
219 {
220 	struct wlan_mlo_dev_context *mlo_dev_ctx = vdev->mlo_dev_ctx;
221 	struct wlan_mlo_sta *sta_ctx = NULL;
222 	uint8_t i = 0;
223 
224 	if (!mlo_dev_ctx)
225 		return;
226 
227 	sta_ctx = mlo_dev_ctx->sta_ctx;
228 	if (!sta_ctx)
229 		return;
230 
231 	for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
232 		if (!mlo_dev_ctx->wlan_vdev_list[i])
233 			continue;
234 
235 		if (vdev == mlo_dev_ctx->wlan_vdev_list[i]) {
236 			if (value)
237 				qdf_set_bit(i, sta_ctx->wlan_connect_req_links);
238 			else
239 				qdf_clear_bit(
240 					i, sta_ctx->wlan_connect_req_links);
241 		}
242 	}
243 }
244 
245 /*
246  * mlo_is_vdev_connect_req_link: API to check if vdev is in active connection
247  *
248  * @vdev: vdev object
249  *
250  * Return: true is vdev is participating in active connect else false
251  */
252 static inline bool
253 mlo_is_vdev_connect_req_link(struct wlan_objmgr_vdev *vdev)
254 {
255 	struct wlan_mlo_dev_context *mlo_dev_ctx = vdev->mlo_dev_ctx;
256 	struct wlan_mlo_sta *sta_ctx = NULL;
257 
258 	if (!mlo_dev_ctx)
259 		return false;
260 
261 	sta_ctx = mlo_dev_ctx->sta_ctx;
262 	if (!sta_ctx)
263 		return false;
264 
265 	if (qdf_test_bit(
266 		mlo_get_link_vdev_ix(vdev->mlo_dev_ctx, vdev),
267 		sta_ctx->wlan_connect_req_links))
268 		return true;
269 
270 	return false;
271 }
272 
273 /*
274  * mlo_clear_connect_req_links: clear connect req links bitmap
275  *
276  * @vdev: vdev object
277  *
278  * Return: none
279  */
280 static inline
281 void mlo_clear_connect_req_links_bmap(struct wlan_objmgr_vdev *vdev)
282 {
283 	struct wlan_mlo_dev_context *mlo_dev_ctx = vdev->mlo_dev_ctx;
284 	struct wlan_mlo_sta *sta_ctx = NULL;
285 
286 	if (!mlo_dev_ctx)
287 		return;
288 
289 	sta_ctx = mlo_dev_ctx->sta_ctx;
290 	if (!sta_ctx)
291 		return;
292 
293 	qdf_mem_zero(sta_ctx->wlan_connect_req_links,
294 		     sizeof(sta_ctx->wlan_connect_req_links));
295 }
296 
297 /*
298  * mlo_update_connected_links: update connected links index
299  *
300  * @vdev: vdev object
301  * @value: set/clear the bit
302  *
303  * Return: none
304  */
305 static inline void
306 mlo_update_connected_links(struct wlan_objmgr_vdev *vdev, uint8_t value)
307 {
308 	struct wlan_mlo_dev_context *mlo_dev_ctx = vdev->mlo_dev_ctx;
309 	struct wlan_mlo_sta *sta_ctx = NULL;
310 	uint8_t i = 0;
311 
312 	if (!mlo_dev_ctx)
313 		return;
314 
315 	sta_ctx = mlo_dev_ctx->sta_ctx;
316 	if (!sta_ctx)
317 		return;
318 
319 	for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
320 		if (!mlo_dev_ctx->wlan_vdev_list[i])
321 			continue;
322 
323 		if (vdev == mlo_dev_ctx->wlan_vdev_list[i]) {
324 			if (value)
325 				qdf_set_bit(i, sta_ctx->wlan_connected_links);
326 			else
327 				qdf_clear_bit(i, sta_ctx->wlan_connected_links);
328 		}
329 	}
330 }
331 
332 /*
333  * mlo_clear_connected_links: clear connected links bitmap
334  *
335  * @vdev: vdev object
336  *
337  * Return: none
338  */
339 static inline
340 void mlo_clear_connected_links_bmap(struct wlan_objmgr_vdev *vdev)
341 {
342 	struct wlan_mlo_dev_context *mlo_dev_ctx = vdev->mlo_dev_ctx;
343 	struct wlan_mlo_sta *sta_ctx = NULL;
344 
345 	if (!mlo_dev_ctx)
346 		return;
347 
348 	sta_ctx = mlo_dev_ctx->sta_ctx;
349 	if (!sta_ctx)
350 		return;
351 
352 	qdf_mem_zero(sta_ctx->wlan_connected_links,
353 		     sizeof(sta_ctx->wlan_connected_links));
354 
355 }
356 
357 #ifndef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
358 /*
359  * mlo_get_ml_vdev_by_mac: get ml vdev from mac
360  *
361  * @vdev: vdev object
362  * @macaddr: mac of vdev to be returned
363  *
364  * Return: vdev object if found else NULL
365  */
366 struct wlan_objmgr_vdev *
367 mlo_get_ml_vdev_by_mac(struct wlan_objmgr_vdev *vdev,
368 		       struct qdf_mac_addr *macaddr);
369 #endif
370 
371 /*
372  * mlo_get_chan_freq_by_bssid - Get channel freq by bssid
373  *
374  * @pdev: pdev pointer
375  * @bssid: link mac address
376  *
377  * Return: chan frequency
378  */
379 qdf_freq_t
380 mlo_get_chan_freq_by_bssid(struct wlan_objmgr_pdev *pdev,
381 			   struct qdf_mac_addr *bssid);
382 
383 /**
384  * mlo_get_assoc_rsp - Get Assoc response from mlo manager
385  *
386  * @vdev: vdev obj mgr
387  * @assoc_rsp_frame: association response frame ptr
388  *
389  * Return: none
390  */
391 void mlo_get_assoc_rsp(struct wlan_objmgr_vdev *vdev,
392 		       struct element_info *assoc_rsp_frame);
393 
394 /**
395  * mlo_sta_save_quiet_status - save quiet status for given link of mlo station
396  * @mlo_dev_ctx: mlo context
397  * @link_id: link id
398  * @quiet_status: True if quiet starts. False if quiet stopps.
399  *
400  * Return: QDF_STATUS
401  */
402 QDF_STATUS mlo_sta_save_quiet_status(struct wlan_mlo_dev_context *mlo_dev_ctx,
403 				     uint8_t link_id,
404 				     bool quiet_status);
405 
406 /**
407  * mlo_is_sta_in_quiet_status - is the link of given mlo sta is in quiet status
408  * @mlo_dev_ctx: mlo context
409  * @link_id: link id
410  *
411  * Return: true if the link of given mlo sta is in quiet status
412  */
413 bool mlo_is_sta_in_quiet_status(struct wlan_mlo_dev_context *mlo_dev_ctx,
414 				uint8_t link_id);
415 
416 /**
417  * mlo_is_sta_inactivity_allowed_with_quiet() - Is link OK to force inactivity
418  *                                              based on current quiet status
419  *                                              of mlo connection
420  * @psoc: pointer to psoc
421  * @vdev_id_list: vdev id list
422  * @num_mlo: number of mlo vdev
423  * @mlo_idx: list of index of vdev_id_list if it is vdev id of mlo vdev
424  * @affected_links: number of links to be set inactivity
425  * @affected_list: list of vdev id to be set inactivity
426  *
427  * Return: true if any link not in mlo_vdev_list is not in quiet mode
428  */
429 bool mlo_is_sta_inactivity_allowed_with_quiet(struct wlan_objmgr_psoc *psoc,
430 					      uint8_t *vdev_id_list,
431 					      uint8_t num_mlo, uint8_t *mlo_idx,
432 					      uint8_t affected_links,
433 					      uint8_t *affected_list);
434 
435 /**
436  * mlo_is_sta_csa_synced - Is mlo sta csa parameters are synced or not
437  *
438  * @mlo_dev_ctx: mlo context
439  * @link_id: link id
440  *
441  * Return: true if mlo sta csa parameters of given link id is synced
442  */
443 bool mlo_is_sta_csa_synced(struct wlan_mlo_dev_context *mlo_dev_ctx,
444 			   uint8_t link_id);
445 
446 /**
447  * mlo_sta_csa_save_params - Save csa parameters for mlo station
448  * @mlo_dev_ctx: mlo context
449  * @link_id: link id
450  * @csa_param: csa parameters to be saved
451  *
452  * Return: QDF_STATUS
453  */
454 QDF_STATUS mlo_sta_csa_save_params(struct wlan_mlo_dev_context *mlo_dev_ctx,
455 				   uint8_t link_id,
456 				   struct csa_offload_params *csa_param);
457 
458 /**
459  * mlo_sta_up_active_notify - mlo sta up active notify
460  * @vdev: vdev obj mgr
461  *
462  * Return: QDF_STATUS
463  */
464 QDF_STATUS mlo_sta_up_active_notify(struct wlan_objmgr_vdev *vdev);
465 
466 /**
467  * mlo_is_sta_csa_param_handled - Is given csa_param handled or not
468  * @vdev: vdev obj mgr
469  * @csa_param: csa parameters to be checked
470  *
471  * Return: true if given csa parameters is handled
472  */
473 bool mlo_is_sta_csa_param_handled(struct wlan_objmgr_vdev *vdev,
474 				  struct csa_offload_params *csa_param);
475 
476 /**
477  * mlo_internal_disconnect_links - Internal disconnect for connection manager
478  *
479  * @vdev: vdev obj mgr
480  *
481  * Return: none
482  */
483 void mlo_internal_disconnect_links(struct wlan_objmgr_vdev *vdev);
484 
485 /**
486  * mlo_sta_get_vdev_list() - get mlo vdev list
487  * @vdev: vdev pointer
488  * @vdev_count: vdev count
489  * @wlan_vdev_list: vdev list
490  *
491  * Return: None
492  */
493 void mlo_sta_get_vdev_list(struct wlan_objmgr_vdev *vdev, uint16_t *vdev_count,
494 			   struct wlan_objmgr_vdev **wlan_vdev_list);
495 #else
496 static inline
497 QDF_STATUS mlo_connect(struct wlan_objmgr_vdev *vdev,
498 		       struct wlan_cm_connect_req *req)
499 {
500 	return wlan_cm_start_connect(vdev, req);
501 }
502 
503 static inline
504 void mlo_sta_link_connect_notify(struct wlan_objmgr_vdev *vdev,
505 				 struct wlan_cm_connect_resp *rsp)
506 { }
507 
508 static inline
509 QDF_STATUS mlo_disconnect(struct wlan_objmgr_vdev *vdev,
510 			  enum wlan_cm_source source,
511 			  enum wlan_reason_code reason_code,
512 			  struct qdf_mac_addr *bssid)
513 {
514 	QDF_STATUS status;
515 
516 	status = wlan_cm_disconnect(vdev, source,
517 				    reason_code,
518 				    bssid);
519 	return status;
520 }
521 
522 static inline
523 QDF_STATUS mlo_sync_disconnect(struct wlan_objmgr_vdev *vdev,
524 			       enum wlan_cm_source source,
525 			       enum wlan_reason_code reason_code,
526 			       struct qdf_mac_addr *bssid)
527 {
528 	return wlan_cm_disconnect_sync(vdev, CM_OSIF_DISCONNECT,
529 				       reason_code);
530 }
531 
532 static inline
533 void mlo_sta_link_disconn_notify(struct wlan_objmgr_vdev *vdev,
534 				 struct wlan_cm_discon_rsp *resp)
535 { }
536 
537 #ifndef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
538 static inline
539 bool ucfg_mlo_is_mld_connected(struct wlan_objmgr_vdev *vdev)
540 {
541 	return true;
542 }
543 
544 static inline
545 bool ucfg_mlo_is_mld_disconnected(struct wlan_objmgr_vdev *vdev)
546 {
547 	return true;
548 }
549 #endif
550 
551 static inline
552 bool mlo_is_mld_sta(struct wlan_objmgr_vdev *vdev)
553 {
554 	return false;
555 }
556 
557 static inline
558 struct wlan_objmgr_vdev *
559 ucfg_mlo_get_assoc_link_vdev(struct wlan_objmgr_vdev *vdev)
560 {
561 	return vdev;
562 }
563 
564 static inline void
565 mlo_update_connect_req_links(struct wlan_objmgr_vdev *vdev, uint8_t value)
566 { }
567 
568 static inline void
569 mlo_update_connected_links_bmap(struct wlan_mlo_dev_context *mlo_dev_ctx,
570 				struct mlo_partner_info ml_parnter_info)
571 { }
572 
573 static inline bool
574 mlo_is_vdev_connect_req_link(struct wlan_objmgr_vdev *vdev)
575 {
576 	return true;
577 }
578 
579 static inline void
580 mlo_update_connected_links(struct wlan_objmgr_vdev *vdev, uint8_t value)
581 { }
582 
583 static inline void
584 mlo_clear_connect_req_links_bmap(struct wlan_objmgr_vdev *vdev)
585 { }
586 
587 static inline void
588 mlo_clear_connected_links_bmap(struct wlan_objmgr_vdev *vdev)
589 { }
590 
591 static inline struct wlan_objmgr_vdev *
592 mlo_get_ml_vdev_by_mac(struct wlan_objmgr_vdev *vdev,
593 		       struct qdf_mac_addr *macaddr)
594 {
595 	return vdev;
596 }
597 
598 static inline qdf_freq_t
599 mlo_get_chan_freq_by_bssid(struct wlan_objmgr_pdev *pdev,
600 			   struct qdf_mac_addr *bssid)
601 {
602 	return 0;
603 }
604 
605 static inline void
606 mlo_get_assoc_rsp(struct wlan_objmgr_vdev *vdev,
607 		  struct element_info *assoc_rsp_frame)
608 {
609 }
610 
611 static inline bool
612 mlo_is_sta_csa_param_handled(struct wlan_objmgr_vdev *vdev,
613 			     struct csa_offload_params *csa_param)
614 {
615 	return false;
616 }
617 
618 static inline void mlo_internal_disconnect_links(struct wlan_objmgr_vdev *vdev)
619 {
620 }
621 
622 static inline
623 void mlo_sta_get_vdev_list(struct wlan_objmgr_vdev *vdev,
624 			   uint16_t *vdev_count,
625 			   struct wlan_objmgr_vdev **wlan_vdev_list)
626 {
627 }
628 #endif
629 #endif
630