xref: /wlan-dirver/qca-wifi-host-cmn/umac/mlo_mgr/inc/utils_mlo.h (revision 901120c066e139c7f8a2c8e4820561fdd83c67ef)
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 Multi-Link
150  * element fragment sequence in a given buffer containing elements, if a
151  * Multi-Link element or element fragment sequence exists in the given buffer.
152  * The buffer should contain only 802.11 Information elements, and thus should
153  * not contain other information like 802.11 header, 802.11 frame body
154  * components like fields that are not elements (e.g. Capability Information
155  * field, Beacon Interval field), etc.
156  *
157  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
158  * the reason for error in the case of failure
159  */
160 QDF_STATUS
161 util_find_mlie(uint8_t *buf, qdf_size_t buflen, uint8_t **mlieseq,
162 	       qdf_size_t *mlieseqlen);
163 
164 /**
165  * util_get_mlie_variant() - Get ML IE variant
166  * @mlieseq: Starting address of the Multi-Link element or Multi-Link element
167  * fragment sequence
168  * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element
169  * fragment sequence
170  * @variant: Pointer to the location where the value of the variant should be
171  * updated. On success, the value should be interpreted by the caller as a
172  * member of enum wlan_ml_variant. (This enum is not directly used as an
173  * argument, so that non-MLO code that happens to call this function does not
174  * need to be aware of the definition of the enum, though such a call would
175  * ultimately result in an error). The value should be ignored by the caller if
176  * the function returns error.
177  *
178  * Get the variant of the given Multi-Link element or element fragment sequence.
179  *
180  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
181  * the reason for error in the case of failure
182  */
183 QDF_STATUS
184 util_get_mlie_variant(uint8_t *mlieseq, qdf_size_t mlieseqlen,
185 		      int *variant);
186 
187 /**
188  * util_get_bvmlie_mldmacaddr() - Get the MLD MAC address
189  * @mlieseq: Starting address of the Multi-Link element or Multi-Link element
190  * fragment sequence
191  * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element
192  * fragment sequence
193  * @linkid: Pointer to the location where the MLD MAC address should be updated.
194  * This should be ignored by the caller if the function returns error.
195  *
196  * Get the MLD MAC address from a given Basic variant Multi-Link element
197  * or element fragment sequence.
198  *
199  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
200  * the reason for error in the case of failure
201  */
202 QDF_STATUS
203 util_get_bvmlie_mldmacaddr(uint8_t *mlieseq, qdf_size_t mlieseqlen,
204 			   struct qdf_mac_addr *mldmacaddr);
205 
206 /**
207  * util_get_bvmlie_eml_cap() - Get the EML capabilities
208  * @mlieseq: Starting address of the Multi-Link element or Multi-Link element
209  * fragment sequence
210  * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element
211  * fragment sequence
212  * @eml_cap_found: Pointer to the location where a boolean status should be
213  * updated indicating whether the EML cabalility was found or not. This should
214  * be ignored by the caller if the function returns error.
215  * @eml_cap: Pointer to the location where the EML capabilities should be
216  * updated. This should be ignored by the caller if the function indicates
217  * that the EML capability was not found.
218  *
219  * Get the EML capabilities from a given Basic variant Multi-Link element or
220  * element fragment sequence.
221  *
222  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
223  * the reason for error in the case of failure
224  */
225 QDF_STATUS
226 util_get_bvmlie_eml_cap(uint8_t *mlieseq, qdf_size_t mlieseqlen,
227 			bool *eml_cap_found,
228 			uint16_t *eml_cap);
229 
230 /**
231  * util_get_bvmlie_msd_cap() - Get the MSD capabilities for Basic variant
232  * MLO IE
233  * @mlieseq: Starting address of the Multi-Link element or Multi-Link element
234  * fragment sequence
235  * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element
236  * fragment sequence
237  * @msd_cap_found: Pointer to the location where a boolean status should be
238  * updated indicating whether the MSD cabalility was found or not. This should
239  * be ignored by the caller if the function returns error.
240  * @msd_cap: Pointer to the location where the MSD capabilities should be
241  * updated. This should be ignored by the caller if the function indicates
242  * that the MSD capability was not found.
243  *
244  * Get the MSD capabilities from a given Basic variant Multi-Link element or
245  * element fragment sequence.
246  *
247  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
248  * the reason for error in the case of failure
249  */
250 QDF_STATUS
251 util_get_bvmlie_msd_cap(uint8_t *mlieseq, qdf_size_t mlieseqlen,
252 			bool *msd_cap_found, uint16_t *msd_cap);
253 /**
254  * util_get_bvmlie_primary_linkid() - Get the link identifier
255  * @mlieseq: Starting address of the Multi-Link element or Multi-Link element
256  * fragment sequence
257  * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element
258  * fragment sequence
259  * @linkidfound: Pointer to the location where a boolean status should be
260  * updated indicating whether the link identifier was found or not. This should
261  * be ignored by the caller if the function returns error.
262  * @linkid: Pointer to the location where the value of the link identifier
263  * should be updated. This should be ignored by the caller if the function
264  * returns error, or if the function indicates that the link identifier was not
265  * found.
266  *
267  * Get the link identifier from a given Basic variant Multi-Link element or
268  * element fragment sequence, of the AP that transmits the Multi-Link
269  * element/element fragment sequence or the nontransmitted BSSID in the same
270  * multiple BSSID set as the AP that transmits the Multi-Link element/element
271  * fragment sequence and that is affiliated with the MLD that is described in
272  * the Multi-Link element.
273  *
274  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
275  * the reason for error in the case of failure
276  */
277 QDF_STATUS
278 util_get_bvmlie_primary_linkid(uint8_t *mlieseq, qdf_size_t mlieseqlen,
279 			       bool *linkidfound, uint8_t *linkid);
280 
281 /**
282  * util_get_mlie_common_info_len() - Get the MLD common info len
283  * @mlieseq: Starting address of the Multi-Link element or Multi-Link element
284  * fragment sequence
285  * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element
286  * fragment sequence
287  * @commoninfo_len: Pointer to the location where the value of the MLD common
288  * info len should be updated. This should be ignored by the caller if the
289  * function returns error.
290  *
291  * Get the MLD common info len from Multi-Link element transmitted by the AP.
292  *
293  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
294  * the reason for error in the case of failure
295  */
296 QDF_STATUS
297 util_get_mlie_common_info_len(uint8_t *mlieseq, qdf_size_t mlieseqlen,
298 			      uint8_t *commoninfo_len);
299 
300 /**
301  * util_get_bvmlie_bssparamchangecnt() - Get the MLD BSS PARAM Change Count
302  * @mlieseq: Starting address of the Multi-Link element or Multi-Link element
303  * fragment sequence
304  * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element
305  * fragment sequence
306  * @bssparamchangecntfound: Pointer to the location where a boolean status
307  * should be updated indicating whether the MLD BSS PARAM Change Count was
308  * found or not. This should be ignored by the caller if the function
309  * returns error.
310  * @bssparamchangecnt: Pointer to the location where the value of the MLD BSS
311  * PARAM Change Count should be updated. This should be ignored by the caller
312  * if the function returns error, or if the function indicates that the MLD
313  * BSS PARAM Change Count was not found.
314  *
315  * Get the MLD BSS PARAM Change Count from Multi-Link element transmitted
316  * by the AP.
317  *
318  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
319  * the reason for error in the case of failure
320  */
321 QDF_STATUS
322 util_get_bvmlie_bssparamchangecnt(uint8_t *mlieseq, qdf_size_t mlieseqlen,
323 				  bool *bssparamchangecntfound,
324 				  uint8_t *bssparamchangecnt);
325 
326 /**
327  * util_get_bvmlie_mldcap() - Get the MLD capabilities
328  * @mlieseq: Starting address of the Multi-Link element or Multi-Link element
329  * fragment sequence
330  * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element
331  * fragment sequence
332  * @mldcapfound: Pointer to the location where a boolean status should be
333  * updated indicating whether the MLD capabilities was found or not. This should
334  * be ignored by the caller if the function returns error.
335  * @mldcap: Pointer to the location where the value of the MLD capabilities
336  * should be updated. This should be ignored by the caller if the function
337  * returns error, or if the function indicates that the MLD capabilities was not
338  * found.
339  *
340  * Get the MLD capabilities from a given Basic variant Multi-Link element or
341  * element fragment sequence, of the AP that transmits the Multi-Link
342  * element/element fragment sequence or the nontransmitted BSSID in the same
343  * multiple BSSID set as the AP that transmits the Multi-Link element/element
344  * fragment sequence and that is affiliated with the MLD that is described in
345  * the Multi-Link element.
346  *
347  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
348  * the reason for error in the case of failure
349  */
350 QDF_STATUS
351 util_get_bvmlie_mldcap(uint8_t *mlieseq, qdf_size_t mlieseqlen,
352 		       bool *mldcapfound, uint16_t *mldcap);
353 
354 /**
355  * util_get_bvmlie_persta_partner_info() - Get per-STA partner link information
356  * @mlieseq: Starting address of the Multi-Link element or Multi-Link element
357  * fragment sequence
358  * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element
359  * fragment sequence
360  * @partner_info: Pointer to the location where the partner link information
361  * should be updated. This should be ignored by the caller if the function
362  * returns error. Note that success will be returned and the number of links in
363  * this structure will be reported as 0, if no Link Info is found, or no per-STA
364  * profile is found, or if none of the per-STA profiles includes a MAC address
365  * in the STA Info field (assuming no errors are encountered).
366  *
367  * Get partner link information in the per-STA profiles present in a Basic
368  * variant Multi-Link element. The partner link information is returned only for
369  * those per-STA profiles which have a MAC address in the STA Info field.
370  *
371  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
372  * the reason for error in the case of failure
373  */
374 QDF_STATUS
375 util_get_bvmlie_persta_partner_info(uint8_t *mlieseq,
376 				    qdf_size_t mlieseqlen,
377 				    struct mlo_partner_info *partner_info);
378 
379 /**
380  * util_get_prvmlie_mldid - Get the MLD ID from a given Probe Request
381  * variant Multi-Link element , of the STA that transmits ML Probe Request
382  * with the Multi-Link element
383  *
384  * @mlieseq: Starting address of the Multi-Link element or Multi-Link element
385  * fragment sequence
386  * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element
387  * fragment sequence
388  * @mldidfound: Pointer to the location where a boolean status should be
389  * updated indicating whether the MLD ID was found or not. This should
390  * be ignored by the caller if the function returns error.
391  * @mldid: Pointer to the location where the value of the MLD ID
392  * should be updated. This should be ignored by the caller if the function
393  * returns error, or if the function indicates that the MLD ID was not
394  * found.
395  *
396  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
397  * the reason for error in the case of failure
398  */
399 QDF_STATUS
400 util_get_prvmlie_mldid(uint8_t *mlieseq, qdf_size_t mlieseqlen,
401 		       bool *mldidfound, uint8_t *mldid);
402 
403 /**
404  * util_get_prvmlie_persta_link_id() - Get per-STA probe req link information
405  *
406  * @mlieseq: Starting address of the Multi-Link element or Multi-Link element
407  * fragment sequence
408  * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element
409  * fragment sequence
410  * @probereq_info: Pointer to the location where the probe req link information
411  * should be updated. This should be ignored by the caller if the function
412  * returns error. Note that success will be returned and the number of links in
413  * this structure will be reported as 0, if no Link Info is found, or no per-STA
414  * profile is found.
415  *
416  * Get probe req link information in the per-STA profiles present in a Probe req
417  * variant Multi-Link element.
418  *
419  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
420  * the reason for error in the case of failure
421  */
422 QDF_STATUS
423 util_get_prvmlie_persta_link_id(uint8_t *mlieseq,
424 				qdf_size_t mlieseqlen,
425 				struct mlo_probereq_info *probereq_info);
426 
427 #else
428 static inline QDF_STATUS
429 util_gen_link_assoc_req(uint8_t *frame, qdf_size_t frame_len, bool isreassoc,
430 			struct qdf_mac_addr link_addr,
431 			uint8_t *link_frame,
432 			qdf_size_t link_frame_maxsize,
433 			qdf_size_t *link_frame_len)
434 {
435 	return QDF_STATUS_E_NOSUPPORT;
436 }
437 
438 static inline QDF_STATUS
439 util_gen_link_assoc_rsp(uint8_t *frame, qdf_size_t frame_len, bool isreassoc,
440 			struct qdf_mac_addr link_addr,
441 			uint8_t *link_frame,
442 			qdf_size_t link_frame_maxsize,
443 			qdf_size_t *link_frame_len)
444 {
445 	return QDF_STATUS_E_NOSUPPORT;
446 }
447 
448 static inline QDF_STATUS
449 util_find_mlie(uint8_t *buf, qdf_size_t buflen, uint8_t **mlieseq,
450 	       qdf_size_t *mlieseqlen)
451 {
452 	return QDF_STATUS_E_NOSUPPORT;
453 }
454 
455 static inline QDF_STATUS
456 util_get_mlie_variant(uint8_t *mlieseq, qdf_size_t mlieseqlen,
457 		      int *variant)
458 {
459 	return QDF_STATUS_E_NOSUPPORT;
460 }
461 
462 static inline QDF_STATUS
463 util_get_mlie_common_info_len(uint8_t *mlieseq, qdf_size_t mlieseqlen,
464 			      uint8_t *commoninfo_len)
465 {
466 	return QDF_STATUS_E_NOSUPPORT;
467 }
468 
469 static inline QDF_STATUS
470 util_get_bvmlie_bssparamchangecnt(uint8_t *mlieseq, qdf_size_t mlieseqlen,
471 				  bool *bssparamchangecntfound,
472 				  uint8_t *bssparamchangecnt)
473 {
474 	return QDF_STATUS_E_NOSUPPORT;
475 }
476 
477 static inline QDF_STATUS
478 util_get_bvmlie_mldmacaddr(uint8_t *mlieseq, qdf_size_t mlieseqlen,
479 			   struct qdf_mac_addr *mldmacaddr)
480 {
481 	return QDF_STATUS_E_NOSUPPORT;
482 }
483 
484 static inline QDF_STATUS
485 util_get_bvmlie_eml_cap(uint8_t *mlieseq, qdf_size_t mlieseqlen,
486 			bool *eml_cap_found,
487 			uint16_t *eml_cap)
488 {
489 	return QDF_STATUS_E_NOSUPPORT;
490 }
491 
492 static inline QDF_STATUS
493 util_get_bvmlie_msd_cap(uint8_t *mlieseq, qdf_size_t mlieseqlen,
494 			bool *msd_cap_found,
495 			uint16_t *msd_cap)
496 {
497 	return QDF_STATUS_E_NOSUPPORT;
498 }
499 
500 static inline QDF_STATUS
501 util_get_bvmlie_primary_linkid(uint8_t *mlieseq, qdf_size_t mlieseqlen,
502 			       bool *linkidfound, uint8_t *linkid)
503 {
504 	return QDF_STATUS_E_NOSUPPORT;
505 }
506 
507 static inline QDF_STATUS
508 util_get_bvmlie_persta_partner_info(uint8_t *mlieseq,
509 				    qdf_size_t mlieseqlen,
510 				    struct mlo_partner_info *partner_info)
511 {
512 	return QDF_STATUS_E_NOSUPPORT;
513 }
514 
515 static inline QDF_STATUS
516 util_get_prvmlie_persta_link_id(uint8_t *mlieseq,
517 				qdf_size_t mlieseqlen,
518 				struct mlo_probereq_info *probereq_info)
519 {
520 	return QDF_STATUS_E_NOSUPPORT;
521 }
522 
523 static inline QDF_STATUS
524 util_get_prvmlie_mldid(uint8_t *mlieseq, qdf_size_t mlieseqlen,
525 		       bool *mldcapfound, uint8_t *mldcap)
526 {
527 	return QDF_STATUS_E_NOSUPPORT;
528 }
529 
530 #endif /* WLAN_FEATURE_11BE_MLO */
531 #endif /* _WLAN_UTILS_MLO_H_ */
532