1 /* 2 * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 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 mandatory API from legacy 20 */ 21 22 #ifndef _WLAN_UTILITY_H_ 23 #define _WLAN_UTILITY_H_ 24 25 #include <qdf_types.h> 26 #include <wlan_objmgr_psoc_obj.h> 27 #include <wlan_objmgr_pdev_obj.h> 28 #include <wlan_objmgr_vdev_obj.h> 29 30 #define TGT_INVALID_SNR (0) 31 #define TGT_MAX_SNR (TGT_NOISE_FLOOR_DBM * (-1)) 32 #define TGT_NOISE_FLOOR_DBM (-96) 33 #define TGT_IS_VALID_SNR(x) ((x) >= 0 && (x) < TGT_MAX_SNR) 34 #define TGT_IS_VALID_RSSI(x) ((x) != 0xFF) 35 36 /** 37 * struct wlan_vdev_ch_check_filter - vdev chan check filter object 38 * @flag: matches or not 39 * @vdev: vdev to be checked against all the active vdevs 40 */ 41 struct wlan_vdev_ch_check_filter { 42 uint8_t flag; 43 struct wlan_objmgr_vdev *vdev; 44 }; 45 46 /** 47 * struct wlan_peer_count- vdev connected peer count 48 * @opmode: QDF mode 49 * @peer_count: peer count 50 **/ 51 struct wlan_op_mode_peer_count { 52 enum QDF_OPMODE opmode; 53 uint16_t peer_count; 54 }; 55 56 /** 57 * wlan_construct_shortssid() - construct the short ssid with the help of 58 * shortssid table 59 * @ssid: pointer to ssid 60 * @ssid_len: ssid length 61 * 62 * return: short ssid length 63 */ 64 uint32_t wlan_construct_shortssid(uint8_t *ssid, uint8_t ssid_len); 65 66 /** 67 * wlan_chan_to_freq() - converts channel to frequency 68 * @chan: channel number 69 * 70 * @return frequency of the channel 71 */ 72 uint32_t wlan_chan_to_freq(uint8_t chan); 73 74 /** 75 * wlan_get_320_center_freq() - find center frequencies for 320Mhz channel 76 * @freq: Primary frequency 77 * @center_freq1: possible 1st center frequency 78 * @center_freq2: possible 2nd center frequency 79 * 80 * return: void 81 **/ 82 void 83 wlan_get_320_center_freq(qdf_freq_t freq, 84 qdf_freq_t *center_freq1, 85 qdf_freq_t *center_freq2); 86 87 /** 88 * wlan_freq_to_chan() - converts frequency to channel 89 * @freq: frequency 90 * 91 * Return: channel of frequency 92 */ 93 uint8_t wlan_freq_to_chan(uint32_t freq); 94 95 /** 96 * wlan_is_ie_valid() - Determine if an IE sequence is valid 97 * @ie: Pointer to the IE buffer 98 * @ie_len: Length of the IE buffer @ie 99 * 100 * This function validates that the IE sequence is valid by verifying 101 * that the sum of the lengths of the embedded elements match the 102 * length of the sequence. 103 * 104 * Note well that a 0-length IE sequence is considered valid. 105 * 106 * Return: true if the IE sequence is valid, false if it is invalid 107 */ 108 bool wlan_is_ie_valid(const uint8_t *ie, size_t ie_len); 109 110 /** 111 * wlan_get_ie_ptr_from_eid() - Find out ie from eid 112 * @eid: element id 113 * @ie: source ie address 114 * @ie_len: source ie length 115 * 116 * Return: vendor ie address - success 117 * NULL - failure 118 */ 119 const uint8_t *wlan_get_ie_ptr_from_eid(uint8_t eid, 120 const uint8_t *ie, 121 int ie_len); 122 123 /** 124 * wlan_get_vendor_ie_ptr_from_oui() - Find out vendor ie 125 * @oui: oui buffer 126 * @oui_size: oui size 127 * @ie: source ie address 128 * @ie_len: source ie length 129 * 130 * This function find out vendor ie by pass source ie and vendor oui. 131 * 132 * Return: vendor ie address - success 133 * NULL - failure 134 */ 135 const uint8_t *wlan_get_vendor_ie_ptr_from_oui(const uint8_t *oui, 136 uint8_t oui_size, 137 const uint8_t *ie, 138 uint16_t ie_len); 139 140 /** 141 * wlan_get_ext_ie_ptr_from_ext_id() - Find out ext ie 142 * @oui: oui buffer 143 * @oui_size: oui size 144 * @ie: source ie address 145 * @ie_len: source ie length 146 * 147 * This function find out ext ie from ext id (passed oui) 148 * 149 * Return: vendor ie address - success 150 * NULL - failure 151 */ 152 const uint8_t *wlan_get_ext_ie_ptr_from_ext_id(const uint8_t *oui, 153 uint8_t oui_size, 154 const uint8_t *ie, 155 uint16_t ie_len); 156 157 /** 158 * wlan_get_elem_fragseq_requirements() - Get requirements related to generation 159 * of element fragment sequence. 160 * 161 * @elemid: Element ID 162 * @payloadlen: Length of element payload to be fragmented. Irrespective of 163 * whether inline fragmentation in wlan_create_elem_fragseq() is to be used or 164 * not, this length should not include the length of the element ID and element 165 * length, and if the element ID is WLAN_ELEMID_EXTN_ELEM, it should not include 166 * the length of the element ID extension. 167 * @is_frag_required: Pointer to location where the function should update 168 * whether fragmentation is required or not for the given element ID and payload 169 * length. The caller should ignore this if the function returns failure. 170 * @required_fragbuff_size: Pointer to location where the function should update 171 * the required minimum size of the buffer where the fragment sequence created 172 * would be written, starting from the beginning of the buffer (irrespective of 173 * whether inline fragmentation in wlan_create_elem_fragseq() is to be used or 174 * not). This is the total size of the element fragment sequence, inclusive of 175 * the header and payload of the leading element and the headers and payloads of 176 * all subsequent fragments applicable to that element. If the element ID is 177 * WLAN_ELEMID_EXTN_ELEM, this also includes the length of the element ID 178 * extension. The caller should ignore this if the function returns a value of 179 * false for is_frag_required, or if the function returns failure. 180 * 181 * Get information on requirements related to generation of element fragment 182 * sequence. Currently this includes an indication of whether fragmentation is 183 * required or not for the given element ID and payload length, and if 184 * fragmentation is applicable, the minimum required size of the buffer where 185 * the fragment sequence created would be written (irrespective of whether 186 * inline fragmentation in wlan_create_elem_fragseq() is to be used or not). 187 * 188 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 189 * the reason for error in the case of failure 190 */ 191 QDF_STATUS 192 wlan_get_elem_fragseq_requirements(uint8_t elemid, 193 qdf_size_t payloadlen, 194 bool *is_frag_required, 195 qdf_size_t *required_fragbuff_size); 196 197 /** 198 * wlan_create_elem_fragseq() - Create sequence of element fragments 199 * 200 * @inline_frag: Whether to use inline fragmentation, wherein the fragmentation 201 * is carried out inline within the source buffer and no memmoves/memcopy would 202 * be required for the lead element. 203 * @elemid: Element ID 204 * @elemidext: Element ID extension. This is applicable only if elemid is 205 * WLAN_ELEMID_EXTN_ELEM, otherwise it is ignored. 206 * @payloadbuff: Buffer containing the element payload to be fragmented. If 207 * inline fragmentation is selected, the corresponding element fragment sequence 208 * will be generated inline into this buffer, and prior to the payload the 209 * buffer should have two bytes reserved in the beginning for the element ID and 210 * element length fields to be written, and a third byte reserved after them for 211 * the element ID extension to be written (if the element ID is 212 * WLAN_ELEMID_EXTN_ELEM). 213 * @payloadbuff_maxsize: Maximum size of payloadbuff 214 * @payloadlen: Length of element payload to be fragmented. Irrespective of 215 * whether inline fragmentation is to be used or not, this should not include 216 * the length of the element ID and element length, and if the element ID is 217 * WLAN_ELEMID_EXTN_ELEM, it should not include the length of the element ID 218 * extension. 219 * @fragbuff: The buffer into which the element fragment sequence should be 220 * generated. This is inapplicable and ignored if inline fragmentation is used. 221 * @fragbuff_maxsize: The maximum size of fragbuff. This is inapplicable and 222 * ignored if inline fragmentation is used. 223 * @fragseqlen: Pointer to location where the length of the fragment sequence 224 * created should be written. This is the total length of the element fragment 225 * sequence, inclusive of the header and payload of the leading element and the 226 * headers and payloads of all subsequent fragments applicable to that element. 227 * If the element ID is WLAN_ELEMID_EXTN_ELEM, this also includes the length of 228 * the element ID extension. The caller should ignore this if the function 229 * returns failure. 230 * 231 * Create a sequence of element fragments. In case fragmentation is not required 232 * for the given element ID and payload length, the function returns an error. 233 * This function is intended to be used by callers which do not have the ability 234 * (or for maintainability purposes do not desire the complexity) to inject new 235 * fragments on the fly where required, when populating the fields in the 236 * element (which would completely eliminate memory moves/copies). An inline 237 * mode is available to carry out the fragmentation within the source buffer in 238 * order to reduce buffer requirements and to eliminate memory copies/moves for 239 * the lead element. In the inline mode, the source buffer should have bytes 240 * reserved in the beginning for the element ID, element length, and if 241 * applicable, the element ID extension. In the inline mode the buffer content 242 * (if any) after the fragments is moved as well. 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 wlan_create_elem_fragseq(bool inline_frag, 248 uint8_t elemid, 249 uint8_t elemidext, 250 uint8_t *payloadbuff, 251 qdf_size_t payloadbuff_maxsize, 252 qdf_size_t payloadlen, 253 uint8_t *fragbuff, 254 qdf_size_t fragbuff_maxsize, 255 qdf_size_t *fragseqlen); 256 257 /** 258 * wlan_get_subelem_fragseq_requirements() - Get requirements related to 259 * generation of subelement fragment sequence. 260 * 261 * @subelemid: Subelement ID 262 * @payloadlen: Length of subelement payload to be fragmented. Irrespective of 263 * whether inline fragmentation in wlan_create_subelem_fragseq() is to be used 264 * or not, this length should not include the length of the subelement ID and 265 * subelement length. 266 * @is_frag_required: Pointer to location where the function should update 267 * whether fragmentation is required or not for the given payload length. The 268 * caller should ignore this if the function returns failure. 269 * @required_fragbuff_size: Pointer to location where the function should update 270 * the required minimum size of the buffer where the fragment sequence created 271 * would be written, starting from the beginning of the buffer (irrespective of 272 * whether inline fragmentation in wlan_create_subelem_fragseq() is to be used 273 * or not). This is the total size of the subelement fragment sequence, 274 * inclusive of the header and payload of the leading subelement and the headers 275 * and payloads of all subsequent fragments applicable to that subelement. The 276 * caller should ignore this if the function returns a value of false for 277 * is_frag_required, or if the function returns failure. 278 * 279 * Get information on requirements related to generation of subelement fragment 280 * sequence. Currently this includes an indication of whether fragmentation is 281 * required or not for the given payload length, and if fragmentation is 282 * applicable, the minimum required size of the buffer where the fragment 283 * sequence created would be written (irrespective of whether inline 284 * fragmentation in wlan_create_subelem_fragseq() is to be used or not). Note 285 * that the subelement ID does not currently play a role in determining the 286 * requirements, but is added as an argument in case it is required in the 287 * future. 288 * 289 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 290 * the reason for error in the case of failure 291 */ 292 QDF_STATUS 293 wlan_get_subelem_fragseq_requirements(uint8_t subelemid, 294 qdf_size_t payloadlen, 295 bool *is_frag_required, 296 qdf_size_t *required_fragbuff_size); 297 298 /** 299 * wlan_create_subelem_fragseq() - Create sequence of subelement fragments 300 * 301 * @inline_frag: Whether to use inline fragmentation, wherein the fragmentation 302 * is carried out inline within the source buffer and no memmoves/memcopy would 303 * be required for the lead subelement. 304 * @subelemid: Subelement ID 305 * @subelemid: Fragment ID to be used for the subelement (this can potentially 306 * vary across protocol areas) 307 * @payloadbuff: Buffer containing the subelement payload to be fragmented. If 308 * inline fragmentation is selected, the corresponding subelement fragment 309 * sequence will be generated inline into this buffer, and prior to the payload 310 * the buffer should have two bytes reserved in the beginning for the subelement 311 * ID and subelement length fields to be written. 312 * @payloadbuff_maxsize: Maximum size of payloadbuff 313 * @payloadlen: Length of subelement payload to be fragmented. Irrespective of 314 * whether inline fragmentation is to be used or not, this should not include 315 * the length of the subelement ID and subelement length. 316 * @fragbuff: The buffer into which the subelement fragment sequence should be 317 * generated. This is inapplicable and ignored if inline fragmentation is used. 318 * @fragbuff_maxsize: The maximum size of fragbuff. This is inapplicable and 319 * ignored if inline fragmentation is used. 320 * @fragseqlen: Pointer to location where the length of the fragment sequence 321 * created should be written. This is the total length of the subelement 322 * fragment sequence, inclusive of the header and payload of the leading 323 * subelement and the headers and payloads of all subsequent fragments 324 * applicable to that subelement. The caller should ignore this if the function 325 * returns failure. 326 * 327 * Create a sequence of subelement fragments. In case fragmentation is not 328 * required for the given payload length, the function returns an error. This 329 * function is intended to be used by callers which do not have the ability (or 330 * for maintainability purposes do not desire the complexity) to inject new 331 * fragments on the fly where required, when populating the fields in the 332 * subelement (which would completely eliminate memory moves/copies). An inline 333 * mode is available to carry out the fragmentation within the source buffer in 334 * order to reduce buffer requirements and to eliminate memory copies/moves for 335 * the lead subelement. In the inline mode, the source buffer should have bytes 336 * reserved in the beginning for the subelement ID and the subelement length. In 337 * the inline mode the buffer content (if any) after the fragments is moved as 338 * well. 339 * 340 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 341 * the reason for error in the case of failure 342 */ 343 QDF_STATUS wlan_create_subelem_fragseq(bool inline_frag, 344 uint8_t subelemid, 345 uint8_t subelemfragid, 346 uint8_t *payloadbuff, 347 qdf_size_t payloadbuff_maxsize, 348 qdf_size_t payloadlen, 349 uint8_t *fragbuff, 350 qdf_size_t fragbuff_maxsize, 351 qdf_size_t *fragseqlen); 352 353 /** 354 * wlan_get_elem_fragseq_info() - Get information about element fragment 355 * sequence 356 * 357 * @elembuff: Buffer containing a series of elements to be checked for whether a 358 * contiguous subset of these elements (starting with the first element in the 359 * buffer) form an element fragment sequence. The buffer should start with the 360 * Element ID of the first element. The buffer should not contain any material 361 * other than elements. 362 * @elembuff_maxsize: Maximum size of elembuff 363 * @is_fragseq: Pointer to location of a flag indicating whether this is an 364 * element fragment sequence or not. The flag will be set to true if elembuff 365 * contains an element fragment sequence starting with the element present in 366 * the beginning of the buffer, or the flag will be set to false if the buffer 367 * contains a single non-fragmented element in the beginning. Please note 368 * standards related limitation given in function description below. 369 * @fragseq_totallen: Pointer to location of total length of element fragment 370 * sequence. If is_fragseq is true, then this is set to the total length of the 371 * element fragment sequence, inclusive of the header and payload of the leading 372 * element and the headers and payloads of all subsequent fragments applicable 373 * to that element. If is_fragseq is false, the caller should ignore this. 374 * Please note standards related limitation given in function description below. 375 * @fragseq_payloadlen: Pointer to location of length of payload of element 376 * fragment sequence. If is_fragseq is true, then this length is set to the 377 * total size of the element fragment sequence payload, which does not include 378 * the sizes of the headers of the lead element and subsequent fragments, and 379 * which (if the lead element's element ID is WLAN_ELEMID_EXTN_ELEM) does not 380 * include the size of the lead element's element ID extension. If is_fragseq is 381 * false, the caller should ignore this. Please note standards related 382 * limitation given in function description below. 383 * 384 * Get the following information for a first element present in the beginning of 385 * a given buffer, and a series of elements after it in the given buffer: a) 386 * Whether a contiguous subset of these elements starting with the first element 387 * form an element fragment sequence. b) If they form an element fragment 388 * sequence, then the total length of this sequence inclusive of headers and 389 * payloads of all the elements in the sequence. c) If they form an element 390 * fragment sequence, then the total size of the payloads of all the elements in 391 * the sequence (not including the element ID extension of the lead element, if 392 * applicable). While determining this information, the function may return 393 * errors, including for protocol parsing issues. These protocol parsing issues 394 * include one in which the first element has a length lesser than 255, but the 395 * very next element after it is a fragment element (which is not allowed by the 396 * standard). Separately, please note a limitation arising from the standard 397 * wherein if the caller passes a truncated maximum buffer size such that the 398 * buffer ends prematurely just at the end of a potential lead element with 399 * length 255 or just at the end of a non-lead fragment element with length 255, 400 * the function will have to conclude that the last successfully parsed element 401 * is the final one in the non-fragment or fragment sequence, and return results 402 * accordingly. If another fragment actually exists beyond the given buffer, 403 * this function cannot detect the condition since there is no provision in the 404 * standard to indicate a total fragment sequence size in one place in the 405 * beginning or anywhere else. Hence the caller should take care to provide the 406 * complete buffer with the max size set accordingly. 407 * 408 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 409 * the reason for error in the case of failure 410 */ 411 QDF_STATUS wlan_get_elem_fragseq_info(uint8_t *elembuff, 412 qdf_size_t elembuff_maxsize, 413 bool *is_fragseq, 414 qdf_size_t *fragseq_totallen, 415 qdf_size_t *fragseq_payloadlen); 416 417 /** 418 * wlan_defrag_elem_fragseq() - Defragment sequence of element fragments 419 * 420 * @inline_defrag: Whether to use inline defragmentation, wherein the 421 * defragmentation is carried out inline within the source buffer and no 422 * memmoves/memcopy would be required for the lead element. 423 * @fragbuff: Source buffer containing the element fragment sequence starting 424 * with the Element ID of the lead element. The buffer should not contain any 425 * material other than elements. If inline defragmentation is enabled, the 426 * corresponding defragmented payload will be generated inline into this buffer 427 * and the defragmented payload will start after the location of the lead 428 * element's element ID, element length, and (if the lead element's element ID 429 * is WLAN_ELEMID_EXTN_ELEM), the element ID extension. This defragmented 430 * payload will not contain the headers of any of the other fragments in the 431 * fragment sequence. 432 * @fragbuff_maxsize: Maximum size of fragbuff. This should be greater than or 433 * equal to the total size of the element fragment sequence, inclusive of the 434 * header and payload of the leading element and the headers and payloads of all 435 * subsequent fragments applicable to that element. 436 * @defragbuff: The destination buffer into which the defragmented payload 437 * should be copied. This is inapplicable and ignored if inline_defrag is true. 438 * The defragmented payload will be copied to the start of the destination 439 * buffer without including the headers of the lead element and the subsequent 440 * fragment elements, and (if the lead element's element ID is 441 * WLAN_ELEMID_EXTN_ELEM), without including the element ID extension. 442 * @defragbuff_maxsize: Maximum size of defragbuff. This is inapplicable and 443 * ignored if inline_defrag is true. The size should be large enough to contain 444 * the entire defragmented payload, otherwise an error will be returned. 445 * @defragpayload_len: Pointer to the location where the length of the 446 * defragmented payload should be updated. Irrespective of whether inline_defrag 447 * is true or false, this will not include the sizes of the headers of the lead 448 * element and subsequent fragments, and (if the lead element's element ID is 449 * WLAN_ELEMID_EXTN_ELEM), it will not include the size of the lead element's 450 * element ID extension. Please note standards related limitation given in 451 * function description below. 452 * 453 * Defragment a sequence of element fragments. If the source buffer does not 454 * contain an element fragment sequence (in the beginning), an error is 455 * returned. An inline mode is available to carry out the defragmentation within 456 * the source buffer in order to reduce buffer requirements and to eliminate 457 * memory copies/moves for the lead element. In the inline mode, the buffer 458 * content (if any) after the fragments is moved as well. The contents of the 459 * defragmented payload are intended for end consumption by control path 460 * protocol processing code within the driver in a manner uniform with other 461 * protocol data in byte buffers, and not for onward forwarding to other 462 * subsystems or for intrusive specialized processing different from other 463 * protocol data. Hence zero copy methods such as network buffer fragment 464 * processing, etc. are not used in this use case. Additionally, this API is 465 * intended for use cases where the nature of the payload is complex and it is 466 * infeasible for the caller to skip the (un-defragmented) fragment boundaries 467 * on its own in a scalable and maintainable manner. Separately, please note a 468 * limitation arising from the standard wherein if the caller passes a truncated 469 * maximum buffer size such that the buffer ends prematurely just at the end of 470 * a fragment element with length 255, the function will have to conclude that 471 * the last successfully parsed fragment element is the final one in the 472 * fragment sequence, and return results accordingly. If another fragment 473 * actually exists beyond the given buffer, this function cannot detect the 474 * condition since there is no provision in the standard to indicate a total 475 * fragment sequence size in one place in the beginning or anywhere else. Hence 476 * the caller should take care to provide the complete buffer with the max size 477 * set accordingly. 478 * 479 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 480 * the reason for error in the case of failure 481 */ 482 QDF_STATUS wlan_defrag_elem_fragseq(bool inline_defrag, 483 uint8_t *fragbuff, 484 qdf_size_t fragbuff_maxsize, 485 uint8_t *defragbuff, 486 qdf_size_t defragbuff_maxsize, 487 qdf_size_t *defragpayload_len); 488 489 /** 490 * wlan_get_subelem_fragseq_info() - Get information about subelement fragment 491 * sequence 492 * 493 * @subelemid: Fragment ID applicable for the subelement (this can potentially 494 * vary across protocol areas) 495 * @subelembuff: Buffer containing a series of subelements to be checked for 496 * whether a contiguous subset of these subelements (starting with the first 497 * subelement in the buffer) form a subelement fragment sequence. The containing 498 * element is required to have already been defragmented (if applicable). The 499 * buffer should start with the subelement ID of the first subelement. The 500 * buffer should not contain any material apart from subelements. 501 * @subelembuff_maxsize: Maximum size of subelembuff 502 * @is_fragseq: Pointer to location of a flag indicating whether this is a 503 * subelement fragment sequence or not. The flag will be set to true if the 504 * buffer contains a subelement fragment sequence starting with the subelement 505 * present in the beginning of the buffer, or the flag will be set to false if 506 * the buffer contains a single non-fragmented subelement in the beginning. 507 * Please note standards related limitation given in function description below. 508 * @fragseq_totallen: Pointer to location of total length of subelement fragment 509 * sequence. If is_fragseq is true, then this is set to the total length of the 510 * subelement fragment sequence, inclusive of the header and payload of the 511 * leading subelement and the headers and payloads of all subsequent fragments 512 * applicable to that subelement. If is_fragseq is false, the caller should 513 * ignore this. Please note standards related limitation given in function 514 * description below. 515 * @fragseq_payloadlen: Pointer to location of length of payload of subelement 516 * fragment sequence. If is_fragseq is true, then this length is set to the 517 * total size of the subelement fragment sequence payload, which does not 518 * include the sizes of the headers of the lead subelement and subsequent 519 * fragments. If is_fragseq is false, the caller should ignore this. Please note 520 * standards related limitation given in function description below. 521 * 522 * Get the following information for a first subelement present in the beginning 523 * of a given buffer, and a series of subelements after it in the given buffer: 524 * a) Whether a contiguous subset of these subelements starting with the first 525 * subelement form a subelement fragment sequence. b) If they form a subelement 526 * fragment sequence, then the total length of this sequence inclusive of 527 * headers and payloads of all the subelements in the sequence. c) If they form 528 * a subelement fragment sequence, then the total size of the payloads of all 529 * the subelements in the sequence. While determining this information, the 530 * function may return errors, including for protocol parsing issues. These 531 * protocol parsing issues include one in which the first subelement has a 532 * length lesser than 255, but the very next subelement after it is a fragment 533 * subelement (which is not allowed by the standard so far). Separately, please 534 * note a limitation arising from the standard wherein if the caller passes a 535 * truncated maximum buffer size such that the buffer ends prematurely just at 536 * the end of a potential lead subelement with length 255 or just at the end of 537 * a non-lead fragment subelement with length 255, the function will have to 538 * conclude that the last successfully parsed subelement is the final one in the 539 * non-fragment or fragment sequence, and return results accordingly. If another 540 * fragment actually exists beyond the given buffer, this function cannot detect 541 * the condition since there is no provision in the standard to indicate a total 542 * fragment sequence size in one place in the beginning or anywhere else. Hence 543 * the caller should take care to provide the complete buffer with the max size 544 * set accordingly. 545 * 546 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 547 * the reason for error in the case of failure 548 */ 549 QDF_STATUS wlan_get_subelem_fragseq_info(uint8_t subelemfragid, 550 uint8_t *subelembuff, 551 qdf_size_t subelembuff_maxsize, 552 bool *is_fragseq, 553 qdf_size_t *fragseq_totallen, 554 qdf_size_t *fragseq_payloadlen); 555 556 /** 557 * wlan_defrag_subelem_fragseq() - Defragment sequence of subelement fragments 558 * 559 * @inline_defrag: Whether to use inline defragmentation, wherein the 560 * defragmentation is carried out inline within the source buffer and no 561 * memmoves/memcopy would be required for the lead subelement. 562 * @subelemid: Fragment ID applicable for the subelement (this can potentially 563 * vary across protocol areas) 564 * @fragbuff: Source buffer containing the subelement fragment sequence starting 565 * with the subelement ID of the lead subelement. The containing element is 566 * required to have already been defragmented (if applicable). If inline 567 * defragmentation is enabled, the corresponding defragmented payload will be 568 * generated inline into this buffer and the defragmented payload will start 569 * after the location of the lead subelement's subelement ID and subelement 570 * length. This defragmented payload will not contain the headers of any of the 571 * other fragments in the fragment sequence. 572 * @fragbuff_maxsize: Maximum size of fragbuff. This should be greater than or 573 * equal to the total size of the subelement fragment sequence, inclusive of the 574 * header and payload of the leading subelement and the headers and payloads of 575 * all subsequent fragments applicable to that subelement. 576 * @defragbuff: The destination buffer into which the defragmented payload 577 * should be copied. This is inapplicable and ignored if inline_defrag is true. 578 * The defragmented payload will be copied to the start of the destination 579 * buffer without including the headers of the lead subelement and the 580 * subsequent fragment subelements. 581 * @defragbuff_maxsize: Maximum size of defragbuff. This is inapplicable and 582 * ignored if inline_defrag is true. The size should be large enough to contain 583 * the entire defragmented payload, otherwise an error will be returned. 584 * @defragpayload_len: Pointer to the location where the length of the 585 * defragmented payload should be updated. Irrespective of whether inline_defrag 586 * is true or false, this will not include the sizes of the headers of the lead 587 * subelement and subsequent fragments. Please note standards related limitation 588 * given in function description below. 589 * 590 * Defragment a sequence of subelement fragments. If the source buffer does not 591 * contain a subelement fragment sequence (in the beginning), the function 592 * returns an error. The containing element is required to have already been 593 * defragmented. An inline mode is available to carry out the defragmentation 594 * within the source buffer in order to reduce buffer requirements and to 595 * eliminate memory copies/moves for the lead subelement. In the inline mode, 596 * the buffer content (if any) after the fragments is moved as well. The 597 * contents of the defragmented payload are intended for end consumption by 598 * control path protocol processing code within the driver in a manner uniform 599 * with other protocol data in byte buffers, and not for onward forwarding to 600 * other subsystems or for intrusive specialized processing different from other 601 * protocol data. Hence zero copy methods such as network buffer fragment 602 * processing, etc. are not used in this use case. Additionally, this API is 603 * intended for use cases where the nature of the payload is complex and it is 604 * infeasible for the caller to skip the (un-defragmented) fragment boundaries 605 * on its own in a scalable and maintainable manner. Separately, please note a 606 * limitation arising from the standard wherein if the caller passes a truncated 607 * maximum buffer size such that the buffer ends prematurely just at the end of 608 * a fragment subelement with length 255, the function will have to conclude 609 * that the last successfully parsed fragment subelement is the final one in the 610 * fragment sequence, and return results accordingly. If another fragment 611 * actually exists beyond the given buffer, this function cannot detect the 612 * condition since there is no provision in the standard to indicate a total 613 * fragment sequence size in one place in the beginning or anywhere else. Hence 614 * the caller should take care to provide the complete buffer with the max size 615 * set accordingly. 616 * 617 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 618 * the reason for error in the case of failure 619 */ 620 QDF_STATUS wlan_defrag_subelem_fragseq(bool inline_defrag, 621 uint8_t subelemfragid, 622 uint8_t *fragbuff, 623 qdf_size_t fragbuff_maxsize, 624 uint8_t *defragbuff, 625 qdf_size_t defragbuff_maxsize, 626 qdf_size_t *defragpayload_len); 627 628 /** 629 * wlan_is_emulation_platform() - check if platform is emulation based 630 * @phy_version - psoc nif phy_version 631 * 632 * Return: boolean value based on platform type 633 */ 634 bool wlan_is_emulation_platform(uint32_t phy_version); 635 636 /** 637 * wlan_get_pdev_id_from_vdev_id() - Helper func to derive pdev id from vdev_id 638 * @psoc: psoc object 639 * @vdev_id: vdev identifier 640 * @dbg_id: object manager debug id 641 * 642 * This function is used to derive the pdev id from vdev id for a psoc 643 * 644 * Return : pdev_id - +ve integer for success and WLAN_INVALID_PDEV_ID 645 * for failure 646 */ 647 uint32_t wlan_get_pdev_id_from_vdev_id(struct wlan_objmgr_psoc *psoc, 648 uint8_t vdev_id, 649 wlan_objmgr_ref_dbgid dbg_id); 650 651 /** 652 * wlan_util_is_vdev_active() - Check for vdev active 653 * @pdev: pdev pointer 654 * @dbg_id: debug id for ref counting 655 * 656 * Return: QDF_STATUS_SUCCESS in case of vdev active 657 * QDF_STATUS_E_INVAL, if dev is not active 658 */ 659 QDF_STATUS wlan_util_is_vdev_active(struct wlan_objmgr_pdev *pdev, 660 wlan_objmgr_ref_dbgid dbg_id); 661 662 /** 663 * wlan_vdev_is_up() - Check for vdev is in UP state 664 * @vdev: vdev pointer 665 * 666 * Return: QDF_STATUS_SUCCESS, if vdev is in up, otherwise QDF_STATUS_E_FAILURE 667 */ 668 QDF_STATUS wlan_vdev_is_up(struct wlan_objmgr_vdev *vdev); 669 670 /** 671 * wlan_util_pdev_vdevs_deschan_match() - function to check des channel matches 672 * with other vdevs in pdev 673 * @pdev: pdev object 674 * @vdev: vdev object 675 * @ref_id: object manager ref id 676 * 677 * This function checks the vdev desired channel with other vdev channels 678 * 679 * Return: QDF_STATUS_SUCCESS, if it matches, otherwise QDF_STATUS_E_FAILURE 680 */ 681 QDF_STATUS wlan_util_pdev_vdevs_deschan_match(struct wlan_objmgr_pdev *pdev, 682 struct wlan_objmgr_vdev *vdev, 683 wlan_objmgr_ref_dbgid dbg_id); 684 685 /** 686 * wlan_util_change_map_index() - function to set/reset given index bit 687 * @map: bitmpap 688 * @id: bit index 689 * @set: 1 for set, 0 of reset 690 * 691 * This function set/reset given index bit 692 * 693 * Return: void 694 */ 695 void wlan_util_change_map_index(unsigned long *map, uint8_t id, uint8_t set); 696 697 /** 698 * wlan_util_map_index_is_set() - function to check whether given index bit is 699 * set 700 * @map: bitmpap 701 * @id: bit index 702 * 703 * This function checks the given index bit is set 704 * 705 * Return: true, if bit is set, otherwise false 706 */ 707 bool wlan_util_map_index_is_set(unsigned long *map, uint8_t id); 708 709 /** 710 * wlan_util_map_is_any_index_set() - Check if any bit is set in given bitmap 711 * @map: bitmap 712 * @nbytes: number of bytes in bitmap 713 * 714 * Return: true, if any of the bit is set, otherwise false 715 */ 716 bool wlan_util_map_is_any_index_set(unsigned long *map, unsigned long nbytes); 717 718 /** 719 * wlan_pdev_chan_change_pending_vdevs() - function to test/set channel change 720 * pending flag 721 * @pdev: pdev object 722 * @vdev_id_map: bitmap to derive channel change vdevs 723 * @ref_id: object manager ref id 724 * 725 * This function test/set channel change pending flag 726 * 727 * Return: QDF_STATUS_SUCCESS, if it iterates through all vdevs, 728 * otherwise QDF_STATUS_E_FAILURE 729 */ 730 QDF_STATUS wlan_pdev_chan_change_pending_vdevs(struct wlan_objmgr_pdev *pdev, 731 unsigned long *vdev_id_map, 732 wlan_objmgr_ref_dbgid dbg_id); 733 734 /** 735 * wlan_pdev_chan_change_pending_vdevs_down() - function to test/set down 736 * change pending flag 737 * @pdev: pdev object 738 * @vdev_id_map: bitmap to derive channel change vdevs 739 * @ref_id: object manager ref id 740 * 741 * This function test/set channel change pending flag 742 * 743 * Return: QDF_STATUS_SUCCESS, if it iterates through all vdevs, 744 * otherwise QDF_STATUS_E_FAILURE 745 */ 746 QDF_STATUS wlan_pdev_chan_change_pending_vdevs_down( 747 struct wlan_objmgr_pdev *pdev, 748 unsigned long *vdev_id_map, 749 wlan_objmgr_ref_dbgid dbg_id); 750 751 /** 752 * wlan_pdev_chan_change_pending_ap_vdevs_down() - function to test/set channel 753 * change pending flag for AP VDEVs 754 * @pdev: pdev object 755 * @vdev_id_map: bitmap to derive channel change AP vdevs 756 * @ref_id: object manager ref id 757 * 758 * This function test/set channel change pending flag for AP vdevs 759 * 760 * Return: QDF_STATUS_SUCCESS, if it iterates through all vdevs, 761 * otherwise QDF_STATUS_E_FAILURE 762 */ 763 QDF_STATUS wlan_pdev_chan_change_pending_ap_vdevs_down( 764 struct wlan_objmgr_pdev *pdev, 765 unsigned long *vdev_id_map, 766 wlan_objmgr_ref_dbgid dbg_id); 767 768 /** 769 * wlan_chan_eq() - function to check whether both channels are same 770 * @chan1: channel1 object 771 * @chan2: channel2 object 772 * 773 * This function checks the chan1 and chan2 are same 774 * 775 * Return: QDF_STATUS_SUCCESS, if it matches, otherwise QDF_STATUS_E_FAILURE 776 */ 777 QDF_STATUS wlan_chan_eq(struct wlan_channel *chan1, struct wlan_channel *chan2); 778 779 /** 780 * wlan_chan_copy() - function to copy channel 781 * @tgt: target channel object 782 * @src: src achannel object 783 * 784 * This function copies channel data from src to tgt 785 * 786 * Return: void 787 */ 788 void wlan_chan_copy(struct wlan_channel *tgt, struct wlan_channel *src); 789 790 /** 791 * wlan_vdev_get_active_channel() - derives the vdev operating channel 792 * @vdev: VDEV object 793 * 794 * This function checks vdev state and return the channel pointer accordingly 795 * 796 * Return: active channel, if vdev chan config is valid 797 * NULL, if VDEV is in INIT or STOP state 798 */ 799 struct wlan_channel *wlan_vdev_get_active_channel 800 (struct wlan_objmgr_vdev *vdev); 801 802 /** 803 * wlan_get_connected_vdev_by_bssid() - check/get any vdev connected on bssid 804 * @pdev: pdev object 805 * @bssid: bssid to be checked 806 * @vdev_id: vdev id 807 * 808 * This function will loop through all the vdev in psoc and find/return the 809 * vdev which is connected to bssid provided. 810 * 811 * Return: bool 812 */ 813 bool wlan_get_connected_vdev_by_bssid(struct wlan_objmgr_pdev *pdev, 814 uint8_t *bssid, uint8_t *vdev_id); 815 816 /** 817 * wlan_get_connected_vdev_from_psoc_by_bssid() - check/get any vdev 818 * connected on bssid 819 * @psoc: psoc object 820 * @bssid: bssid to be checked 821 * @vdev_id: vdev id 822 * 823 * This function will loop through all the vdev in psoc and find/return the 824 * vdev which is connected to bssid provided. 825 * 826 * Return: bool 827 */ 828 bool wlan_get_connected_vdev_from_psoc_by_bssid(struct wlan_objmgr_psoc *psoc, 829 uint8_t *bssid, 830 uint8_t *vdev_id); 831 832 #ifdef WLAN_FEATURE_11BE_MLO 833 /** 834 * wlan_get_connected_vdev_by_mld_addr() - check/get any vdev 835 * connected on mld mac 836 * @psoc: psoc object 837 * @mld_mac: mld mac to be checked 838 * @vdev_id: vdev id 839 * 840 * This function will loop through all the vdev in psoc and find/return the 841 * first vdev which is connected to mld mac provided. 842 * 843 * Return: bool 844 */ 845 bool wlan_get_connected_vdev_by_mld_addr(struct wlan_objmgr_psoc *psoc, 846 uint8_t *mld_mac, uint8_t *vdev_id); 847 #endif 848 849 /** 850 * wlan_util_stats_get_rssi() - API to get rssi in dbm 851 * @db2dbm_enabled: If db2dbm capability is enabled 852 * @bcn_snr: beacon snr 853 * @dat_snr: data snr 854 * @rssi: rssi 855 * 856 * This function gets the rssi based on db2dbm support. If this feature is 857 * present in hw then it means firmware directly sends rssi and no conversion 858 * is required. If this capability is not present then host needs to convert 859 * snr to rssi 860 * 861 * Return: None 862 */ 863 void 864 wlan_util_stats_get_rssi(bool db2dbm_enabled, int32_t bcn_snr, int32_t dat_snr, 865 int8_t *rssi); 866 867 /** 868 * wlan_util_is_pdev_restart_progress() - Check if any vdev is in restart state 869 * @pdev: pdev pointer 870 * @dbg_id: module id 871 * 872 * Iterates through all vdevs, checks if any VDEV is in RESTART_PROGRESS 873 * substate 874 * 875 * Return: QDF_STATUS_SUCCESS,if any vdev is in RESTART_PROGRESS substate 876 * otherwise QDF_STATUS_E_FAILURE 877 */ 878 QDF_STATUS wlan_util_is_pdev_restart_progress(struct wlan_objmgr_pdev *pdev, 879 wlan_objmgr_ref_dbgid dbg_id); 880 881 /** 882 * wlan_util_is_pdev_scan_allowed() - Check for vdev is allowed to scan 883 * @pdev: pdev pointer 884 * @dbg_id: module id 885 * 886 * Iterates through all vdevs, checks if any VDEV is not either in S_INIT or in 887 * S_UP state 888 * 889 * Return: QDF_STATUS_SUCCESS,if scan is allowed, otherwise QDF_STATUS_E_FAILURE 890 */ 891 QDF_STATUS wlan_util_is_pdev_scan_allowed(struct wlan_objmgr_pdev *pdev, 892 wlan_objmgr_ref_dbgid dbg_id); 893 894 /** 895 * wlan_util_get_peer_count_for_mode - This api gives vdev mode specific 896 * peer count` 897 * @pdev: PDEV object 898 * @mode: Operation mode. 899 * 900 * Return: int- peer count for operating mode 901 */ 902 uint16_t wlan_util_get_peer_count_for_mode(struct wlan_objmgr_pdev *pdev, 903 enum QDF_OPMODE mode); 904 905 /** 906 * wlan_minidump_host_data - Data structure type logged in Minidump 907 * @WLAN_MD_CP_EXT_PDEV - ol_ath_softc_net80211 908 * @WLAN_MD_CP_EXT_PSOC - ol_ath_soc_softc 909 * @WLAN_MD_CP_EXT_VDEV - ieee80211vap 910 * @WLAN_MD_CP_EXT_PEER - ieee80211_node 911 * @WLAN_MD_DP_SOC - dp_soc 912 * @WLAN_MD_DP_PDEV - dp_pdev 913 * @WLAN_MD_DP_VDEV - dp_vdev 914 * @WLAN_MD_DP_PEER - dp_peer 915 * @WLAN_MD_DP_SRNG_REO_DEST - dp_srng type for reo dest 916 * @WLAN_MD_DP_SRNG_REO_EXCEPTION - dp_srng type for reo exception 917 * @WLAN_MD_DP_SRNG_REO_CMD - dp_srng type for reo cmd 918 * @WLAN_MD_DP_SRNG_RX_REL - dp_srng type for reo release 919 * @WLAN_MD_DP_SRNG_REO_REINJECT - dp_srng type for reo reinject 920 * @WLAN_MD_DP_SRNG_REO_STATUS - dp_srng type for reo status 921 * @WLAN_MD_DP_SRNG_TCL_DATA - dp_srng type for tcl data 922 * @WLAN_MD_DP_SRNG_TCL_STATUS - dp_srng type for tcl status 923 * @WLAN_MD_DP_SRNG_TX_COMP - dp_srng type for tcl comp 924 * @WLAN_MD_DP_SRNG_WBM_DESC_REL - dp_srng_type for wbm desc rel 925 * @WLAN_MD_DP_SRNG_WBM_IDLE_LINK - dp_srng type for wbm idle link 926 * @WLAN_MD_DP_LINK_DESC_BANK - Wbm link_desc_bank 927 * @WLAN_MD_DP_SRNG_RXDMA_MON_STATUS - dp_srng type for rxdma mon status 928 * @WLAN_MD_DP_SRNG_RXDMA_MON_BUF - dp_srng type for rxdma mon buf 929 * @WLAN_MD_DP_SRNG_RXDMA_MON_DST - dp_srng type for rxdma mon dest 930 * @WLAN_MD_DP_SRNG_RXDMA_MON_DESC - dp_srng type for rxdma mon desc 931 * @WLAN_MD_DP_SRNG_RXDMA_ERR_DST - dp_srng type for rxdma err dst 932 * @WLAN_MD_DP_HAL_SOC - hal_soc 933 * @WLAN_MD_OBJMGR_PSOC - wlan_objmgr_psoc 934 * @WLAN_MD_OBJMGR_PSOC_TGT_INFO - wlan_objmgr_tgt_psoc_info 935 * @WLAN_MD_OBJMGR_PDEV - wlan_objmgr_pdev 936 * @WLAN_MD_OBJMGR_PDEV_MLME - pdev_mlme 937 * @WLAN_MD_OBJMGR_VDEV - wlan_objmgr_vdev 938 * @WLAN_MD_OBJMGR_VDEV_MLME -vdev mlme 939 * @WLAN_MD_OBJMGR_VDEV_SM - wlan_sm 940 * @WLAN_MD_DP_SRNG_REO2PPE- dp_srng type PPE rx ring 941 * @WLAN_MD_DP_SRNG_PPE2TCL - dp_srng type for PPE tx ring 942 * @WLAN_MD_DP_SRNG_PPE_RELEASE - dp_srng type for PPE tx com ring 943 * @WLAN_MD_MAX - Max value 944 */ 945 enum wlan_minidump_host_data { 946 WLAN_MD_CP_EXT_PDEV, 947 WLAN_MD_CP_EXT_PSOC, 948 WLAN_MD_CP_EXT_VDEV, 949 WLAN_MD_CP_EXT_PEER, 950 WLAN_MD_DP_SOC, 951 WLAN_MD_DP_PDEV, 952 WLAN_MD_DP_VDEV, 953 WLAN_MD_DP_PEER, 954 WLAN_MD_DP_SRNG_REO_DEST, 955 WLAN_MD_DP_SRNG_REO_EXCEPTION, 956 WLAN_MD_DP_SRNG_REO_CMD, 957 WLAN_MD_DP_SRNG_RX_REL, 958 WLAN_MD_DP_SRNG_REO_REINJECT, 959 WLAN_MD_DP_SRNG_REO_STATUS, 960 WLAN_MD_DP_SRNG_TCL_DATA, 961 WLAN_MD_DP_SRNG_TCL_CMD, 962 WLAN_MD_DP_SRNG_TCL_STATUS, 963 WLAN_MD_DP_SRNG_TX_COMP, 964 WLAN_MD_DP_SRNG_WBM_DESC_REL, 965 WLAN_MD_DP_SRNG_WBM_IDLE_LINK, 966 WLAN_MD_DP_LINK_DESC_BANK, 967 WLAN_MD_DP_SRNG_RXDMA_MON_STATUS, 968 WLAN_MD_DP_SRNG_RXDMA_MON_BUF, 969 WLAN_MD_DP_SRNG_RXDMA_MON_DST, 970 WLAN_MD_DP_SRNG_RXDMA_MON_DESC, 971 WLAN_MD_DP_SRNG_RXDMA_ERR_DST, 972 WLAN_MD_DP_HAL_SOC, 973 WLAN_MD_OBJMGR_PSOC, 974 WLAN_MD_OBJMGR_PSOC_TGT_INFO, 975 WLAN_MD_OBJMGR_PDEV, 976 WLAN_MD_OBJMGR_PDEV_MLME, 977 WLAN_MD_OBJMGR_VDEV, 978 WLAN_MD_OBJMGR_VDEV_MLME, 979 WLAN_MD_OBJMGR_VDEV_SM, 980 WLAN_MD_DP_SRNG_REO2PPE, 981 WLAN_MD_DP_SRNG_PPE2TCL, 982 WLAN_MD_DP_SRNG_PPE_RELEASE, 983 WLAN_MD_MAX 984 }; 985 986 /** 987 * wlan_minidump_log() - Log memory address to be included in minidump 988 * @start_addr: Start address of the memory to be dumped 989 * @size: Size in bytes 990 * @psoc_obj: Psoc Object 991 * @type: Type of data structure 992 * @name: String to identify this entry 993 */ 994 void wlan_minidump_log(void *start_addr, const size_t size, 995 void *psoc_obj, 996 enum wlan_minidump_host_data type, 997 const char *name); 998 999 /** 1000 * wlan_minidump_remove() - Remove memory address from minidump 1001 * @start_addr: Start address of the memory previously added 1002 * @size: Size in bytes 1003 * @psoc_obj: Psoc Object 1004 * @type: Type of data structure 1005 * @name: String to identify this entry 1006 */ 1007 void wlan_minidump_remove(void *start_addr, const size_t size, 1008 void *psoc_obj, 1009 enum wlan_minidump_host_data type, 1010 const char *name); 1011 1012 #endif /* _WLAN_UTILITY_H_ */ 1013