xref: /wlan-dirver/qca-wifi-host-cmn/umac/mlo_mgr/inc/utils_mlo.h (revision 2888b71da71bce103343119fa1b31f4a0cee07c8)
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 containing util public api's
20  */
21 #ifndef _WLAN_UTILS_MLO_H_
22 #define _WLAN_UTILS_MLO_H_
23 
24 #include <wlan_cmn_ieee80211.h>
25 #include "wlan_mlo_mgr_public_structs.h"
26 #include <wlan_cm_ucfg_api.h>
27 #include <wlan_objmgr_vdev_obj.h>
28 
29 #ifdef WLAN_FEATURE_11BE_MLO
30 
31 /**
32  * util_gen_link_assoc_req() - Generate link specific assoc request
33  * @frame: Pointer to original association request. This should not contain the
34  * 802.11 header, and must start from the fixed fields in the association
35  * request. This is required due to some caller semantics built into the end to
36  * end design.
37  * @frame_len: Length of original association request
38  * @isreassoc: Whether this is a re-association request
39  * @link_addr: Secondary link's MAC address
40  * @link_frame: Generated secondary link specific association request. Note that
41  * this will start from the 802.11 header (unlike the original association
42  * request). This should be ignored in the case of failure.
43  * @link_frame_maxsize: Maximum size of generated secondary link specific
44  * association request
45  * @link_frame_len: Pointer to location where populated length of generated
46  * secondary link specific association request should be written. This should be
47  * ignored in the case of failure.
48  *
49  * Generate a link specific logically equivalent association request for the
50  * secondary link from the original association request containing a Multi-Link
51  * element. This applies to both association and re-association requests.
52  * Currently, only two link MLO is supported.
53  *
54  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
55  * the reason for error in the case of failure.
56  */
57 QDF_STATUS
58 util_gen_link_assoc_req(uint8_t *frame, qdf_size_t frame_len, bool isreassoc,
59 			struct qdf_mac_addr link_addr,
60 			uint8_t *link_frame,
61 			qdf_size_t link_frame_maxsize,
62 			qdf_size_t *link_frame_len);
63 
64 /**
65  * util_gen_link_assoc_rsp() - Generate link specific assoc response
66  * @frame: Pointer to original association response. This should not contain the
67  * 802.11 header, and must start from the fixed fields in the association
68  * response. This is required due to some caller semantics built into the end to
69  * end design.
70  * @frame_len: Length of original association response
71  * @isreassoc: Whether this is a re-association response
72  * @link_addr: Secondary link's MAC address
73  * @link_frame: Generated secondary link specific association response. Note
74  * that this will start from the 802.11 header (unlike the original association
75  * response). This should be ignored in the case of failure.
76  * @link_frame_maxsize: Maximum size of generated secondary link specific
77  * association response
78  * @link_frame_len: Pointer to location where populated length of generated
79  * secondary link specific association response should be written. This should
80  * be ignored in the case of failure.
81  *
82  * Generate a link specific logically equivalent association response for the
83  * secondary link from the original association response containing a Multi-Link
84  * element. This applies to both association and re-association responses.
85  * Currently, only two link MLO is supported.
86  *
87  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
88  * the reason for error in the case of failure.
89  */
90 QDF_STATUS
91 util_gen_link_assoc_rsp(uint8_t *frame, qdf_size_t frame_len, bool isreassoc,
92 			struct qdf_mac_addr link_addr,
93 			uint8_t *link_frame,
94 			qdf_size_t link_frame_maxsize,
95 			qdf_size_t *link_frame_len);
96 
97 /**
98  * util_gen_link_probe_rsp() - Generate link specific probe response
99  * @frame: Pointer to original probe response. This should not contain the
100  * 802.11 header, and must start from the fixed fields in the probe
101  * response. This is required due to some caller semantics built into the end to
102  * end design.
103  * @frame_len: Length of original probe response
104  * @link_addr: Secondary link's MAC address
105  * @link_frame: Generated secondary link specific probe response. Note
106  * that this will start from the 802.11 header (unlike the original probe
107  * response). This should be ignored in the case of failure.
108  * @link_frame_maxsize: Maximum size of generated secondary link specific
109  * probe response
110  * @link_frame_len: Pointer to location where populated length of generated
111  * secondary link specific probe response should be written. This should
112  * be ignored in the case of failure.
113  *
114  * Generate a link specific logically equivalent probe response for the
115  * secondary link from the original probe response containing a Multi-Link
116  * element. This applies to both probe responses.
117  * Currently, only two link MLO is supported.
118  *
119  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
120  * the reason for error in the case of failure.
121  */
122 QDF_STATUS
123 util_gen_link_probe_rsp(uint8_t *frame, qdf_size_t frame_len,
124 			struct qdf_mac_addr link_addr,
125 			uint8_t *link_frame,
126 			qdf_size_t link_frame_maxsize,
127 			qdf_size_t *link_frame_len);
128 
129 /**
130  * util_find_mlie - Find the first Multi-Link element or the start of the first
131  * Multi-Link element fragment sequence in a given buffer containing elements,
132  * if a Multi-Link element or element fragment sequence exists in the given
133  * buffer.
134  *
135  * @buf: Buffer to be searched for the Multi-Link element or the start of the
136  * Multi-Link element fragment sequence
137  * @buflen: Length of the buffer
138  * @mlieseq: Pointer to location where the starting address of the Multi-Link
139  * element or Multi-Link element fragment sequence should be updated if found
140  * in the given buffer. The value NULL will be updated to this location if the
141  * element or element fragment sequence is not found. This should be ignored by
142  * the caller if the function returns error.
143  * @mlieseqlen: Pointer to location where the total length of the Multi-Link
144  * element or Multi-Link element fragment sequence should be updated if found
145  * in the given buffer. This should be ignored by the caller if the function
146  * returns error, or if the function indicates that the element or element
147  * fragment sequence was not found by providing a starting address of NULL.
148  *
149  * Find the first Multi-Link element or the start of the first
150  * Multi-Link element fragment sequence in a given buffer containing elements,
151  * if a Multi-Link element or element fragment sequence exists in the given
152  * buffer.
153  *
154  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
155  * the reason for error in the case of failure
156  */
157 QDF_STATUS
158 util_find_mlie(uint8_t *buf, qdf_size_t buflen, uint8_t **mlieseq,
159 	       qdf_size_t *mlieseqlen);
160 
161 /**
162  * util_get_mlie_variant() - Get ML IE variant
163  * @mlieseq: Starting address of the Multi-Link element or Multi-Link element
164  * fragment sequence
165  * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element
166  * fragment sequence
167  * @variant: Pointer to the location where the value of the variant should be
168  * updated. On success, the value should be interpreted by the caller as a
169  * member of enum wlan_ml_variant. (This enum is not directly used as an
170  * argument, so that non-MLO code that happens to call this function does not
171  * need to be aware of the definition of the enum, though such a call would
172  * ultimately result in an error). The value should be ignored by the caller if
173  * the function returns error.
174  *
175  * Get the variant of the given Multi-Link element or element fragment sequence.
176  *
177  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
178  * the reason for error in the case of failure
179  */
180 QDF_STATUS
181 util_get_mlie_variant(uint8_t *mlieseq, qdf_size_t mlieseqlen,
182 		      int *variant);
183 
184 /**
185  * util_get_bvmlie_mldmacaddr() - Get the MLD MAC address
186  * @mlieseq: Starting address of the Multi-Link element or Multi-Link element
187  * fragment sequence
188  * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element
189  * fragment sequence
190  * @linkid: Pointer to the location where the MLD MAC address should be updated.
191  * This should be ignored by the caller if the function returns error.
192  *
193  * Get the MLD MAC address from a given Basic variant Multi-Link element
194  * or element fragment sequence.
195  *
196  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
197  * the reason for error in the case of failure
198  */
199 QDF_STATUS
200 util_get_bvmlie_mldmacaddr(uint8_t *mlieseq, qdf_size_t mlieseqlen,
201 			   struct qdf_mac_addr *mldmacaddr);
202 
203 /**
204  * util_get_bvmlie_eml_cap() - Get the EML capabilities
205  * @mlieseq: Starting address of the Multi-Link element or Multi-Link element
206  * fragment sequence
207  * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element
208  * fragment sequence
209  * @eml_cap_found: Pointer to the location where a boolean status should be
210  * updated indicating whether the EML cabalility was found or not. This should
211  * be ignored by the caller if the function returns error.
212  * @eml_cap: Pointer to the location where the EML capabilities should be
213  * updated. This should be ignored by the caller if the function indicates
214  * that the EML capability was not found.
215  *
216  * Get the EML capabilities from a given Basic variant Multi-Link element or
217  * element fragment sequence.
218  *
219  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
220  * the reason for error in the case of failure
221  */
222 QDF_STATUS
223 util_get_bvmlie_eml_cap(uint8_t *mlieseq, qdf_size_t mlieseqlen,
224 			bool *eml_cap_found,
225 			uint16_t *eml_cap);
226 
227 /**
228  * util_get_bvmlie_msd_cap() - Get the MSD capabilities for Basic variant
229  * MLO IE
230  * @mlieseq: Starting address of the Multi-Link element or Multi-Link element
231  * fragment sequence
232  * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element
233  * fragment sequence
234  * @msd_cap_found: Pointer to the location where a boolean status should be
235  * updated indicating whether the MSD cabalility was found or not. This should
236  * be ignored by the caller if the function returns error.
237  * @msd_cap: Pointer to the location where the MSD capabilities should be
238  * updated. This should be ignored by the caller if the function indicates
239  * that the MSD capability was not found.
240  *
241  * Get the MSD capabilities from a given Basic variant Multi-Link element or
242  * element fragment sequence.
243  *
244  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
245  * the reason for error in the case of failure
246  */
247 QDF_STATUS
248 util_get_bvmlie_msd_cap(uint8_t *mlieseq, qdf_size_t mlieseqlen,
249 			bool *msd_cap_found, uint16_t *msd_cap);
250 /**
251  * util_get_bvmlie_primary_linkid() - Get the link identifier
252  * @mlieseq: Starting address of the Multi-Link element or Multi-Link element
253  * fragment sequence
254  * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element
255  * fragment sequence
256  * @linkidfound: Pointer to the location where a boolean status should be
257  * updated indicating whether the link identifier was found or not. This should
258  * be ignored by the caller if the function returns error.
259  * @linkid: Pointer to the location where the value of the link identifier
260  * should be updated. This should be ignored by the caller if the function
261  * returns error, or if the function indicates that the link identifier was not
262  * found.
263  *
264  * Get the link identifier from a given Basic variant Multi-Link element or
265  * element fragment sequence, of the AP that transmits the Multi-Link
266  * element/element fragment sequence or the nontransmitted BSSID in the same
267  * multiple BSSID set as the AP that transmits the Multi-Link element/element
268  * fragment sequence and that is affiliated with the MLD that is described in
269  * the Multi-Link element.
270  *
271  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
272  * the reason for error in the case of failure
273  */
274 QDF_STATUS
275 util_get_bvmlie_primary_linkid(uint8_t *mlieseq, qdf_size_t mlieseqlen,
276 			       bool *linkidfound, uint8_t *linkid);
277 
278 /**
279  * util_get_mlie_common_info_len() - Get the MLD common info len
280  * @mlieseq: Starting address of the Multi-Link element or Multi-Link element
281  * fragment sequence
282  * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element
283  * fragment sequence
284  * @commoninfo_len: Pointer to the location where the value of the MLD common
285  * info len should be updated. This should be ignored by the caller if the
286  * function returns error.
287  *
288  * Get the MLD common info len from Multi-Link element transmitted by the AP.
289  *
290  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
291  * the reason for error in the case of failure
292  */
293 QDF_STATUS
294 util_get_mlie_common_info_len(uint8_t *mlieseq, qdf_size_t mlieseqlen,
295 			      uint8_t *commoninfo_len);
296 
297 /**
298  * util_get_bvmlie_bssparamchangecnt() - Get the MLD BSS PARAM Change Count
299  * @mlieseq: Starting address of the Multi-Link element or Multi-Link element
300  * fragment sequence
301  * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element
302  * fragment sequence
303  * @bssparamchangecntfound: Pointer to the location where a boolean status
304  * should be updated indicating whether the MLD BSS PARAM Change Count was
305  * found or not. This should be ignored by the caller if the function
306  * returns error.
307  * @bssparamchangecnt: Pointer to the location where the value of the MLD BSS
308  * PARAM Change Count should be updated. This should be ignored by the caller
309  * if the function returns error, or if the function indicates that the MLD
310  * BSS PARAM Change Count was not found.
311  *
312  * Get the MLD BSS PARAM Change Count from Multi-Link element transmitted
313  * by the AP.
314  *
315  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
316  * the reason for error in the case of failure
317  */
318 QDF_STATUS
319 util_get_bvmlie_bssparamchangecnt(uint8_t *mlieseq, qdf_size_t mlieseqlen,
320 				  bool *bssparamchangecntfound,
321 				  uint8_t *bssparamchangecnt);
322 
323 /**
324  * util_get_bvmlie_mldcap() - Get the MLD capabilities
325  * @mlieseq: Starting address of the Multi-Link element or Multi-Link element
326  * fragment sequence
327  * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element
328  * fragment sequence
329  * @mldcapfound: Pointer to the location where a boolean status should be
330  * updated indicating whether the MLD capabilities was found or not. This should
331  * be ignored by the caller if the function returns error.
332  * @mldcap: Pointer to the location where the value of the MLD capabilities
333  * should be updated. This should be ignored by the caller if the function
334  * returns error, or if the function indicates that the MLD capabilities was not
335  * found.
336  *
337  * Get the MLD capabilities from a given Basic variant Multi-Link element or
338  * element fragment sequence, of the AP that transmits the Multi-Link
339  * element/element fragment sequence or the nontransmitted BSSID in the same
340  * multiple BSSID set as the AP that transmits the Multi-Link element/element
341  * fragment sequence and that is affiliated with the MLD that is described in
342  * the Multi-Link element.
343  *
344  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
345  * the reason for error in the case of failure
346  */
347 QDF_STATUS
348 util_get_bvmlie_mldcap(uint8_t *mlieseq, qdf_size_t mlieseqlen,
349 		       bool *mldcapfound, uint16_t *mldcap);
350 
351 /**
352  * util_get_bvmlie_persta_partner_info() - Get per-STA partner link information
353  * @mlieseq: Starting address of the Multi-Link element or Multi-Link element
354  * fragment sequence
355  * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element
356  * fragment sequence
357  * @partner_info: Pointer to the location where the partner link information
358  * should be updated. This should be ignored by the caller if the function
359  * returns error. Note that success will be returned and the number of links in
360  * this structure will be reported as 0, if no Link Info is found, or no per-STA
361  * profile is found, or if none of the per-STA profiles includes a MAC address
362  * in the STA Info field (assuming no errors are encountered).
363  *
364  * Get partner link information in the per-STA profiles present in a Basic
365  * variant Multi-Link element. The partner link information is returned only for
366  * those per-STA profiles which have a MAC address in the STA Info field.
367  *
368  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
369  * the reason for error in the case of failure
370  */
371 QDF_STATUS
372 util_get_bvmlie_persta_partner_info(uint8_t *mlieseq,
373 				    qdf_size_t mlieseqlen,
374 				    struct mlo_partner_info *partner_info);
375 
376 /**
377  * util_get_prvmlie_mldid - Get the MLD ID from a given Probe Request
378  * variant Multi-Link element , of the STA that transmits ML Probe Request
379  * with the Multi-Link element
380  *
381  * @mlieseq: Starting address of the Multi-Link element or Multi-Link element
382  * fragment sequence
383  * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element
384  * fragment sequence
385  * @mldidfound: Pointer to the location where a boolean status should be
386  * updated indicating whether the MLD ID was found or not. This should
387  * be ignored by the caller if the function returns error.
388  * @mldid: Pointer to the location where the value of the MLD ID
389  * should be updated. This should be ignored by the caller if the function
390  * returns error, or if the function indicates that the MLD ID was not
391  * found.
392  *
393  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
394  * the reason for error in the case of failure
395  */
396 QDF_STATUS
397 util_get_prvmlie_mldid(uint8_t *mlieseq, qdf_size_t mlieseqlen,
398 		       bool *mldidfound, uint8_t *mldid);
399 
400 /**
401  * util_get_prvmlie_persta_link_id() - Get per-STA probe req link information
402  *
403  * @mlieseq: Starting address of the Multi-Link element or Multi-Link element
404  * fragment sequence
405  * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element
406  * fragment sequence
407  * @probereq_info: Pointer to the location where the probe req link information
408  * should be updated. This should be ignored by the caller if the function
409  * returns error. Note that success will be returned and the number of links in
410  * this structure will be reported as 0, if no Link Info is found, or no per-STA
411  * profile is found.
412  *
413  * Get probe req link information in the per-STA profiles present in a Probe req
414  * variant Multi-Link element.
415  *
416  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
417  * the reason for error in the case of failure
418  */
419 QDF_STATUS
420 util_get_prvmlie_persta_link_id(uint8_t *mlieseq,
421 				qdf_size_t mlieseqlen,
422 				struct mlo_probereq_info *probereq_info);
423 
424 #else
425 static inline QDF_STATUS
426 util_gen_link_assoc_req(uint8_t *frame, qdf_size_t frame_len, bool isreassoc,
427 			struct qdf_mac_addr link_addr,
428 			uint8_t *link_frame,
429 			qdf_size_t link_frame_maxsize,
430 			qdf_size_t *link_frame_len)
431 {
432 	return QDF_STATUS_E_NOSUPPORT;
433 }
434 
435 static inline QDF_STATUS
436 util_gen_link_assoc_rsp(uint8_t *frame, qdf_size_t frame_len, bool isreassoc,
437 			struct qdf_mac_addr link_addr,
438 			uint8_t *link_frame,
439 			qdf_size_t link_frame_maxsize,
440 			qdf_size_t *link_frame_len)
441 {
442 	return QDF_STATUS_E_NOSUPPORT;
443 }
444 
445 static inline QDF_STATUS
446 util_find_mlie(uint8_t *buf, qdf_size_t buflen, uint8_t **mlieseq,
447 	       qdf_size_t *mlieseqlen)
448 {
449 	return QDF_STATUS_E_NOSUPPORT;
450 }
451 
452 static inline QDF_STATUS
453 util_get_mlie_variant(uint8_t *mlieseq, qdf_size_t mlieseqlen,
454 		      int *variant)
455 {
456 	return QDF_STATUS_E_NOSUPPORT;
457 }
458 
459 static inline QDF_STATUS
460 util_get_mlie_common_info_len(uint8_t *mlieseq, qdf_size_t mlieseqlen,
461 			      uint8_t *commoninfo_len)
462 {
463 	return QDF_STATUS_E_NOSUPPORT;
464 }
465 
466 static inline QDF_STATUS
467 util_get_bvmlie_bssparamchangecnt(uint8_t *mlieseq, qdf_size_t mlieseqlen,
468 				  bool *bssparamchangecntfound,
469 				  uint8_t *bssparamchangecnt)
470 {
471 	return QDF_STATUS_E_NOSUPPORT;
472 }
473 
474 static inline QDF_STATUS
475 util_get_bvmlie_mldmacaddr(uint8_t *mlieseq, qdf_size_t mlieseqlen,
476 			   struct qdf_mac_addr *mldmacaddr)
477 {
478 	return QDF_STATUS_E_NOSUPPORT;
479 }
480 
481 static inline QDF_STATUS
482 util_get_bvmlie_eml_cap(uint8_t *mlieseq, qdf_size_t mlieseqlen,
483 			bool *eml_cap_found,
484 			uint16_t *eml_cap)
485 {
486 	return QDF_STATUS_E_NOSUPPORT;
487 }
488 
489 static inline QDF_STATUS
490 util_get_bvmlie_msd_cap(uint8_t *mlieseq, qdf_size_t mlieseqlen,
491 			bool *msd_cap_found,
492 			uint16_t *msd_cap)
493 {
494 	return QDF_STATUS_E_NOSUPPORT;
495 }
496 
497 static inline QDF_STATUS
498 util_get_bvmlie_primary_linkid(uint8_t *mlieseq, qdf_size_t mlieseqlen,
499 			       bool *linkidfound, uint8_t *linkid)
500 {
501 	return QDF_STATUS_E_NOSUPPORT;
502 }
503 
504 static inline QDF_STATUS
505 util_get_bvmlie_persta_partner_info(uint8_t *mlieseq,
506 				    qdf_size_t mlieseqlen,
507 				    struct mlo_partner_info *partner_info)
508 {
509 	return QDF_STATUS_E_NOSUPPORT;
510 }
511 
512 static inline QDF_STATUS
513 util_get_prvmlie_persta_link_id(uint8_t *mlieseq,
514 				qdf_size_t mlieseqlen,
515 				struct mlo_probereq_info *probereq_info)
516 {
517 	return QDF_STATUS_E_NOSUPPORT;
518 }
519 
520 static inline QDF_STATUS
521 util_get_prvmlie_mldid(uint8_t *mlieseq, qdf_size_t mlieseqlen,
522 		       bool *mldcapfound, uint8_t *mldcap)
523 {
524 	return QDF_STATUS_E_NOSUPPORT;
525 }
526 
527 #endif /* WLAN_FEATURE_11BE_MLO */
528 #endif /* _WLAN_UTILS_MLO_H_ */
529