xref: /wlan-dirver/qca-wifi-host-cmn/umac/mlo_mgr/inc/wlan_mlo_mgr_sta.h (revision 19ceffca9d494f2431432fa8123aa187c91cb4fb)
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 #else
476 static inline
477 QDF_STATUS mlo_connect(struct wlan_objmgr_vdev *vdev,
478 		       struct wlan_cm_connect_req *req)
479 {
480 	return wlan_cm_start_connect(vdev, req);
481 }
482 
483 static inline
484 void mlo_sta_link_connect_notify(struct wlan_objmgr_vdev *vdev,
485 				 struct wlan_cm_connect_resp *rsp)
486 { }
487 
488 static inline
489 QDF_STATUS mlo_disconnect(struct wlan_objmgr_vdev *vdev,
490 			  enum wlan_cm_source source,
491 			  enum wlan_reason_code reason_code,
492 			  struct qdf_mac_addr *bssid)
493 {
494 	QDF_STATUS status;
495 
496 	status = wlan_cm_disconnect(vdev, source,
497 				    reason_code,
498 				    bssid);
499 	return status;
500 }
501 
502 static inline
503 QDF_STATUS mlo_sync_disconnect(struct wlan_objmgr_vdev *vdev,
504 			       enum wlan_cm_source source,
505 			       enum wlan_reason_code reason_code,
506 			       struct qdf_mac_addr *bssid)
507 {
508 	return wlan_cm_disconnect_sync(vdev, CM_OSIF_DISCONNECT,
509 				       reason_code);
510 }
511 
512 static inline
513 void mlo_sta_link_disconn_notify(struct wlan_objmgr_vdev *vdev,
514 				 struct wlan_cm_discon_rsp *resp)
515 { }
516 
517 #ifndef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
518 static inline
519 bool ucfg_mlo_is_mld_connected(struct wlan_objmgr_vdev *vdev)
520 {
521 	return true;
522 }
523 
524 static inline
525 bool ucfg_mlo_is_mld_disconnected(struct wlan_objmgr_vdev *vdev)
526 {
527 	return true;
528 }
529 #endif
530 
531 static inline
532 bool mlo_is_mld_sta(struct wlan_objmgr_vdev *vdev)
533 {
534 	return false;
535 }
536 
537 static inline
538 struct wlan_objmgr_vdev *
539 ucfg_mlo_get_assoc_link_vdev(struct wlan_objmgr_vdev *vdev)
540 {
541 	return vdev;
542 }
543 
544 static inline void
545 mlo_update_connect_req_links(struct wlan_objmgr_vdev *vdev, uint8_t value)
546 { }
547 
548 static inline void
549 mlo_update_connected_links_bmap(struct wlan_mlo_dev_context *mlo_dev_ctx,
550 				struct mlo_partner_info ml_parnter_info)
551 { }
552 
553 static inline bool
554 mlo_is_vdev_connect_req_link(struct wlan_objmgr_vdev *vdev)
555 {
556 	return true;
557 }
558 
559 static inline void
560 mlo_update_connected_links(struct wlan_objmgr_vdev *vdev, uint8_t value)
561 { }
562 
563 static inline void
564 mlo_clear_connect_req_links_bmap(struct wlan_objmgr_vdev *vdev)
565 { }
566 
567 static inline void
568 mlo_clear_connected_links_bmap(struct wlan_objmgr_vdev *vdev)
569 { }
570 
571 static inline struct wlan_objmgr_vdev *
572 mlo_get_ml_vdev_by_mac(struct wlan_objmgr_vdev *vdev,
573 		       struct qdf_mac_addr *macaddr)
574 {
575 	return vdev;
576 }
577 
578 static inline qdf_freq_t
579 mlo_get_chan_freq_by_bssid(struct wlan_objmgr_pdev *pdev,
580 			   struct qdf_mac_addr *bssid)
581 {
582 	return 0;
583 }
584 
585 static inline void
586 mlo_get_assoc_rsp(struct wlan_objmgr_vdev *vdev,
587 		  struct element_info *assoc_rsp_frame)
588 {
589 }
590 
591 static inline bool
592 mlo_is_sta_csa_param_handled(struct wlan_objmgr_vdev *vdev,
593 			     struct csa_offload_params *csa_param)
594 {
595 	return false;
596 }
597 #endif
598 #endif
599