Fichiers
android_kernel_samsung_sm86…/umac/cmn_services/utils/inc/wlan_utility.h
Aasir Rasheed 1bd26224ae qcacmn: Reconfigure the link info when csa is received
Reconfigure the link information structure for the partner
links and assoc link when a channel switch event is received.

Change-Id: I022bb6c6e2bcf43a1efaa6234e52648142b9fde2
CRs-Fixed: 3599451
2023-09-13 14:20:52 -07:00

1074 lignes
46 KiB
C

/*
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: Contains mandatory API from legacy
*/
#ifndef _WLAN_UTILITY_H_
#define _WLAN_UTILITY_H_
#include <qdf_types.h>
#include <wlan_objmgr_psoc_obj.h>
#include <wlan_objmgr_pdev_obj.h>
#include <wlan_objmgr_vdev_obj.h>
#define TGT_INVALID_SNR (0)
#define TGT_MAX_SNR (TGT_NOISE_FLOOR_DBM * (-1))
#define TGT_NOISE_FLOOR_DBM (-96)
#define TGT_IS_VALID_SNR(x) ((x) >= 0 && (x) < TGT_MAX_SNR)
#define TGT_IS_VALID_RSSI(x) ((x) != 0xFF)
/**
* struct wlan_vdev_ch_check_filter - vdev chan check filter object
* @flag: matches or not
* @vdev: vdev to be checked against all the active vdevs
*/
struct wlan_vdev_ch_check_filter {
uint8_t flag;
struct wlan_objmgr_vdev *vdev;
};
/**
* struct wlan_op_mode_peer_count - vdev connected peer count
* @opmode: QDF mode
* @peer_count: peer count
**/
struct wlan_op_mode_peer_count {
enum QDF_OPMODE opmode;
uint16_t peer_count;
};
/**
* wlan_construct_shortssid() - construct the short ssid with the help of
* shortssid table
* @ssid: pointer to ssid
* @ssid_len: ssid length
*
* return: short ssid length
*/
uint32_t wlan_construct_shortssid(uint8_t *ssid, uint8_t ssid_len);
/**
* wlan_chan_to_freq() - converts channel to frequency
* @chan: channel number
*
* @return frequency of the channel
*/
uint32_t wlan_chan_to_freq(uint8_t chan);
/**
* wlan_get_320_center_freq() - find center frequencies for 320Mhz channel
* @freq: Primary frequency
* @center_freq1: possible 1st center frequency
* @center_freq2: possible 2nd center frequency
*
* return: void
**/
void
wlan_get_320_center_freq(qdf_freq_t freq,
qdf_freq_t *center_freq1,
qdf_freq_t *center_freq2);
/**
* wlan_freq_to_chan() - converts frequency to channel
* @freq: frequency
*
* Return: channel of frequency
*/
uint8_t wlan_freq_to_chan(uint32_t freq);
/**
* wlan_is_ie_valid() - Determine if an IE sequence is valid
* @ie: Pointer to the IE buffer
* @ie_len: Length of the IE buffer @ie
*
* This function validates that the IE sequence is valid by verifying
* that the sum of the lengths of the embedded elements match the
* length of the sequence.
*
* Note well that a 0-length IE sequence is considered valid.
*
* Return: true if the IE sequence is valid, false if it is invalid
*/
bool wlan_is_ie_valid(const uint8_t *ie, size_t ie_len);
/**
* wlan_get_ie_ptr_from_eid() - Find out ie from eid
* @eid: element id
* @ie: source ie address
* @ie_len: source ie length
*
* Return: vendor ie address - success
* NULL - failure
*/
const uint8_t *wlan_get_ie_ptr_from_eid(uint8_t eid,
const uint8_t *ie,
int ie_len);
/**
* wlan_get_vendor_ie_ptr_from_oui() - Find out vendor ie
* @oui: oui buffer
* @oui_size: oui size
* @ie: source ie address
* @ie_len: source ie length
*
* This function find out vendor ie by pass source ie and vendor oui.
*
* Return: vendor ie address - success
* NULL - failure
*/
const uint8_t *wlan_get_vendor_ie_ptr_from_oui(const uint8_t *oui,
uint8_t oui_size,
const uint8_t *ie,
uint16_t ie_len);
/**
* wlan_get_ext_ie_ptr_from_ext_id() - Find out ext ie
* @oui: oui buffer
* @oui_size: oui size
* @ie: source ie address
* @ie_len: source ie length
*
* This function find out ext ie from ext id (passed oui)
*
* Return: vendor ie address - success
* NULL - failure
*/
const uint8_t *wlan_get_ext_ie_ptr_from_ext_id(const uint8_t *oui,
uint8_t oui_size,
const uint8_t *ie,
uint16_t ie_len);
/**
* wlan_iecap_set() - Set the capability in the IE
* @iecap: pointer to capability IE
* @bit_pos: bit position of capability from start of capability field
* @tot_bits: total bits of capability
* @value: value to be set
*
* This function sets the value in capability IE at the bit position
* specified for specified number of bits in byte order.
*
* Return: void
*/
void wlan_iecap_set(uint8_t *iecap,
uint8_t bit_pos,
uint8_t tot_bits,
uint32_t value);
/**
* wlan_iecap_get() - Get the capability in the IE
* @iecap: pointer to capability IE
* @bit_pos: bit position of capability from start of capability field
* @tot_bits: total bits of capability
*
* This function gets the value at bit position for specified bits
* from start of capability field.
*
* Return: capability value
*/
uint32_t wlan_iecap_get(uint8_t *iecap,
uint8_t bit_pos,
uint32_t tot_bits);
/**
* wlan_get_elem_fragseq_requirements() - Get requirements related to generation
* of element fragment sequence.
*
* @elemid: Element ID
* @payloadlen: Length of element payload to be fragmented. Irrespective of
* whether inline fragmentation in wlan_create_elem_fragseq() is to be used or
* not, this length should not include the length of the element ID and element
* length, and if the element ID is WLAN_ELEMID_EXTN_ELEM, it should not include
* the length of the element ID extension.
* @is_frag_required: Pointer to location where the function should update
* whether fragmentation is required or not for the given element ID and payload
* length. The caller should ignore this if the function returns failure.
* @required_fragbuff_size: Pointer to location where the function should update
* the required minimum size of the buffer where the fragment sequence created
* would be written, starting from the beginning of the buffer (irrespective of
* whether inline fragmentation in wlan_create_elem_fragseq() is to be used or
* not). This is the total size of the element fragment sequence, inclusive of
* the header and payload of the leading element and the headers and payloads of
* all subsequent fragments applicable to that element. If the element ID is
* WLAN_ELEMID_EXTN_ELEM, this also includes the length of the element ID
* extension. The caller should ignore this if the function returns a value of
* false for is_frag_required, or if the function returns failure.
*
* Get information on requirements related to generation of element fragment
* sequence. Currently this includes an indication of whether fragmentation is
* required or not for the given element ID and payload length, and if
* fragmentation is applicable, the minimum required size of the buffer where
* the fragment sequence created would be written (irrespective of whether
* inline fragmentation in wlan_create_elem_fragseq() is to be used or not).
*
* Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
* the reason for error in the case of failure
*/
QDF_STATUS
wlan_get_elem_fragseq_requirements(uint8_t elemid,
qdf_size_t payloadlen,
bool *is_frag_required,
qdf_size_t *required_fragbuff_size);
/**
* wlan_create_elem_fragseq() - Create sequence of element fragments
*
* @inline_frag: Whether to use inline fragmentation, wherein the fragmentation
* is carried out inline within the source buffer and no memmoves/memcopy would
* be required for the lead element.
* @elemid: Element ID
* @elemidext: Element ID extension. This is applicable only if elemid is
* WLAN_ELEMID_EXTN_ELEM, otherwise it is ignored.
* @payloadbuff: Buffer containing the element payload to be fragmented. If
* inline fragmentation is selected, the corresponding element fragment sequence
* will be generated inline into this buffer, and prior to the payload the
* buffer should have two bytes reserved in the beginning for the element ID and
* element length fields to be written, and a third byte reserved after them for
* the element ID extension to be written (if the element ID is
* WLAN_ELEMID_EXTN_ELEM).
* @payloadbuff_maxsize: Maximum size of payloadbuff
* @payloadlen: Length of element payload to be fragmented. Irrespective of
* whether inline fragmentation is to be used or not, this should not include
* the length of the element ID and element length, and if the element ID is
* WLAN_ELEMID_EXTN_ELEM, it should not include the length of the element ID
* extension.
* @fragbuff: The buffer into which the element fragment sequence should be
* generated. This is inapplicable and ignored if inline fragmentation is used.
* @fragbuff_maxsize: The maximum size of fragbuff. This is inapplicable and
* ignored if inline fragmentation is used.
* @fragseqlen: Pointer to location where the length of the fragment sequence
* created should be written. This is the total length of the element fragment
* sequence, inclusive of the header and payload of the leading element and the
* headers and payloads of all subsequent fragments applicable to that element.
* If the element ID is WLAN_ELEMID_EXTN_ELEM, this also includes the length of
* the element ID extension. The caller should ignore this if the function
* returns failure.
*
* Create a sequence of element fragments. In case fragmentation is not required
* for the given element ID and payload length, the function returns an error.
* This function is intended to be used by callers which do not have the ability
* (or for maintainability purposes do not desire the complexity) to inject new
* fragments on the fly where required, when populating the fields in the
* element (which would completely eliminate memory moves/copies). An inline
* mode is available to carry out the fragmentation within the source buffer in
* order to reduce buffer requirements and to eliminate memory copies/moves for
* the lead element. In the inline mode, the source buffer should have bytes
* reserved in the beginning for the element ID, element length, and if
* applicable, the element ID extension. In the inline mode the buffer content
* (if any) after the fragments is moved as well.
*
* Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
* the reason for error in the case of failure
*/
QDF_STATUS wlan_create_elem_fragseq(bool inline_frag,
uint8_t elemid,
uint8_t elemidext,
uint8_t *payloadbuff,
qdf_size_t payloadbuff_maxsize,
qdf_size_t payloadlen,
uint8_t *fragbuff,
qdf_size_t fragbuff_maxsize,
qdf_size_t *fragseqlen);
/**
* wlan_get_subelem_fragseq_requirements() - Get requirements related to
* generation of subelement fragment sequence.
*
* @subelemid: Subelement ID
* @payloadlen: Length of subelement payload to be fragmented. Irrespective of
* whether inline fragmentation in wlan_create_subelem_fragseq() is to be used
* or not, this length should not include the length of the subelement ID and
* subelement length.
* @is_frag_required: Pointer to location where the function should update
* whether fragmentation is required or not for the given payload length. The
* caller should ignore this if the function returns failure.
* @required_fragbuff_size: Pointer to location where the function should update
* the required minimum size of the buffer where the fragment sequence created
* would be written, starting from the beginning of the buffer (irrespective of
* whether inline fragmentation in wlan_create_subelem_fragseq() is to be used
* or not). This is the total size of the subelement fragment sequence,
* inclusive of the header and payload of the leading subelement and the headers
* and payloads of all subsequent fragments applicable to that subelement. The
* caller should ignore this if the function returns a value of false for
* is_frag_required, or if the function returns failure.
*
* Get information on requirements related to generation of subelement fragment
* sequence. Currently this includes an indication of whether fragmentation is
* required or not for the given payload length, and if fragmentation is
* applicable, the minimum required size of the buffer where the fragment
* sequence created would be written (irrespective of whether inline
* fragmentation in wlan_create_subelem_fragseq() is to be used or not). Note
* that the subelement ID does not currently play a role in determining the
* requirements, but is added as an argument in case it is required in the
* future.
*
* Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
* the reason for error in the case of failure
*/
QDF_STATUS
wlan_get_subelem_fragseq_requirements(uint8_t subelemid,
qdf_size_t payloadlen,
bool *is_frag_required,
qdf_size_t *required_fragbuff_size);
/**
* wlan_create_subelem_fragseq() - Create sequence of subelement fragments
*
* @inline_frag: Whether to use inline fragmentation, wherein the fragmentation
* is carried out inline within the source buffer and no memmoves/memcopy would
* be required for the lead subelement.
* @subelemid: Subelement ID
* @subelemfragid: Fragment ID to be used for the subelement (this can
* potentially vary across protocol areas)
* @payloadbuff: Buffer containing the subelement payload to be fragmented. If
* inline fragmentation is selected, the corresponding subelement fragment
* sequence will be generated inline into this buffer, and prior to the payload
* the buffer should have two bytes reserved in the beginning for the subelement
* ID and subelement length fields to be written.
* @payloadbuff_maxsize: Maximum size of payloadbuff
* @payloadlen: Length of subelement payload to be fragmented. Irrespective of
* whether inline fragmentation is to be used or not, this should not include
* the length of the subelement ID and subelement length.
* @fragbuff: The buffer into which the subelement fragment sequence should be
* generated. This is inapplicable and ignored if inline fragmentation is used.
* @fragbuff_maxsize: The maximum size of fragbuff. This is inapplicable and
* ignored if inline fragmentation is used.
* @fragseqlen: Pointer to location where the length of the fragment sequence
* created should be written. This is the total length of the subelement
* fragment sequence, inclusive of the header and payload of the leading
* subelement and the headers and payloads of all subsequent fragments
* applicable to that subelement. The caller should ignore this if the function
* returns failure.
*
* Create a sequence of subelement fragments. In case fragmentation is not
* required for the given payload length, the function returns an error. This
* function is intended to be used by callers which do not have the ability (or
* for maintainability purposes do not desire the complexity) to inject new
* fragments on the fly where required, when populating the fields in the
* subelement (which would completely eliminate memory moves/copies). An inline
* mode is available to carry out the fragmentation within the source buffer in
* order to reduce buffer requirements and to eliminate memory copies/moves for
* the lead subelement. In the inline mode, the source buffer should have bytes
* reserved in the beginning for the subelement ID and the subelement length. In
* the inline mode the buffer content (if any) after the fragments is moved as
* well.
*
* Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
* the reason for error in the case of failure
*/
QDF_STATUS wlan_create_subelem_fragseq(bool inline_frag,
uint8_t subelemid,
uint8_t subelemfragid,
uint8_t *payloadbuff,
qdf_size_t payloadbuff_maxsize,
qdf_size_t payloadlen,
uint8_t *fragbuff,
qdf_size_t fragbuff_maxsize,
qdf_size_t *fragseqlen);
/**
* wlan_get_elem_fragseq_info() - Get information about element fragment
* sequence
*
* @elembuff: Buffer containing a series of elements to be checked for whether a
* contiguous subset of these elements (starting with the first element in the
* buffer) form an element fragment sequence. The buffer should start with the
* Element ID of the first element. The buffer should not contain any material
* other than elements.
* @elembuff_maxsize: Maximum size of elembuff
* @is_fragseq: Pointer to location of a flag indicating whether this is an
* element fragment sequence or not. The flag will be set to true if elembuff
* contains an element fragment sequence starting with the element present in
* the beginning of the buffer, or the flag will be set to false if the buffer
* contains a single non-fragmented element in the beginning. Please note
* standards related limitation given in function description below.
* @fragseq_totallen: Pointer to location of total length of element fragment
* sequence. If is_fragseq is true, then this is set to the total length of the
* element fragment sequence, inclusive of the header and payload of the leading
* element and the headers and payloads of all subsequent fragments applicable
* to that element. If is_fragseq is false, the caller should ignore this.
* Please note standards related limitation given in function description below.
* @fragseq_payloadlen: Pointer to location of length of payload of element
* fragment sequence. If is_fragseq is true, then this length is set to the
* total size of the element fragment sequence payload, which does not include
* the sizes of the headers of the lead element and subsequent fragments, and
* which (if the lead element's element ID is WLAN_ELEMID_EXTN_ELEM) does not
* include the size of the lead element's element ID extension. If is_fragseq is
* false, the caller should ignore this. Please note standards related
* limitation given in function description below.
*
* Get the following information for a first element present in the beginning of
* a given buffer, and a series of elements after it in the given buffer: a)
* Whether a contiguous subset of these elements starting with the first element
* form an element fragment sequence. b) If they form an element fragment
* sequence, then the total length of this sequence inclusive of headers and
* payloads of all the elements in the sequence. c) If they form an element
* fragment sequence, then the total size of the payloads of all the elements in
* the sequence (not including the element ID extension of the lead element, if
* applicable). While determining this information, the function may return
* errors, including for protocol parsing issues. These protocol parsing issues
* include one in which the first element has a length lesser than 255, but the
* very next element after it is a fragment element (which is not allowed by the
* standard). Separately, please note a limitation arising from the standard
* wherein if the caller passes a truncated maximum buffer size such that the
* buffer ends prematurely just at the end of a potential lead element with
* length 255 or just at the end of a non-lead fragment element with length 255,
* the function will have to conclude that the last successfully parsed element
* is the final one in the non-fragment or fragment sequence, and return results
* accordingly. If another fragment actually exists beyond the given buffer,
* this function cannot detect the condition since there is no provision in the
* standard to indicate a total fragment sequence size in one place in the
* beginning or anywhere else. Hence the caller should take care to provide the
* complete buffer with the max size set accordingly.
*
* Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
* the reason for error in the case of failure
*/
QDF_STATUS wlan_get_elem_fragseq_info(uint8_t *elembuff,
qdf_size_t elembuff_maxsize,
bool *is_fragseq,
qdf_size_t *fragseq_totallen,
qdf_size_t *fragseq_payloadlen);
/**
* wlan_defrag_elem_fragseq() - Defragment sequence of element fragments
*
* @inline_defrag: Whether to use inline defragmentation, wherein the
* defragmentation is carried out inline within the source buffer and no
* memmoves/memcopy would be required for the lead element.
* @fragbuff: Source buffer containing the element fragment sequence starting
* with the Element ID of the lead element. The buffer should not contain any
* material other than elements. If inline defragmentation is enabled, the
* corresponding defragmented payload will be generated inline into this buffer
* and the defragmented payload will start after the location of the lead
* element's element ID, element length, and (if the lead element's element ID
* is WLAN_ELEMID_EXTN_ELEM), the element ID extension. This defragmented
* payload will not contain the headers of any of the other fragments in the
* fragment sequence.
* @fragbuff_maxsize: Maximum size of fragbuff. This should be greater than or
* equal to the total size of the element fragment sequence, inclusive of the
* header and payload of the leading element and the headers and payloads of all
* subsequent fragments applicable to that element.
* @defragbuff: The destination buffer into which the defragmented payload
* should be copied. This is inapplicable and ignored if inline_defrag is true.
* The defragmented payload will be copied to the start of the destination
* buffer without including the headers of the lead element and the subsequent
* fragment elements, and (if the lead element's element ID is
* WLAN_ELEMID_EXTN_ELEM), without including the element ID extension.
* @defragbuff_maxsize: Maximum size of defragbuff. This is inapplicable and
* ignored if inline_defrag is true. The size should be large enough to contain
* the entire defragmented payload, otherwise an error will be returned.
* @defragpayload_len: Pointer to the location where the length of the
* defragmented payload should be updated. Irrespective of whether inline_defrag
* is true or false, this will not include the sizes of the headers of the lead
* element and subsequent fragments, and (if the lead element's element ID is
* WLAN_ELEMID_EXTN_ELEM), it will not include the size of the lead element's
* element ID extension. Please note standards related limitation given in
* function description below.
*
* Defragment a sequence of element fragments. If the source buffer does not
* contain an element fragment sequence (in the beginning), an error is
* returned. An inline mode is available to carry out the defragmentation within
* the source buffer in order to reduce buffer requirements and to eliminate
* memory copies/moves for the lead element. In the inline mode, the buffer
* content (if any) after the fragments is moved as well. The contents of the
* defragmented payload are intended for end consumption by control path
* protocol processing code within the driver in a manner uniform with other
* protocol data in byte buffers, and not for onward forwarding to other
* subsystems or for intrusive specialized processing different from other
* protocol data. Hence zero copy methods such as network buffer fragment
* processing, etc. are not used in this use case. Additionally, this API is
* intended for use cases where the nature of the payload is complex and it is
* infeasible for the caller to skip the (un-defragmented) fragment boundaries
* on its own in a scalable and maintainable manner. Separately, please note a
* limitation arising from the standard wherein if the caller passes a truncated
* maximum buffer size such that the buffer ends prematurely just at the end of
* a fragment element with length 255, the function will have to conclude that
* the last successfully parsed fragment element is the final one in the
* fragment sequence, and return results accordingly. If another fragment
* actually exists beyond the given buffer, this function cannot detect the
* condition since there is no provision in the standard to indicate a total
* fragment sequence size in one place in the beginning or anywhere else. Hence
* the caller should take care to provide the complete buffer with the max size
* set accordingly.
*
* Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
* the reason for error in the case of failure
*/
QDF_STATUS wlan_defrag_elem_fragseq(bool inline_defrag,
uint8_t *fragbuff,
qdf_size_t fragbuff_maxsize,
uint8_t *defragbuff,
qdf_size_t defragbuff_maxsize,
qdf_size_t *defragpayload_len);
/**
* wlan_get_subelem_fragseq_info() - Get information about subelement fragment
* sequence
*
* @subelemfragid: Fragment ID applicable for the subelement (this can
* potentially vary across protocol areas)
* @subelembuff: Buffer containing a series of subelements to be checked for
* whether a contiguous subset of these subelements (starting with the first
* subelement in the buffer) form a subelement fragment sequence. The containing
* element is required to have already been defragmented (if applicable). The
* buffer should start with the subelement ID of the first subelement. The
* buffer should not contain any material apart from subelements.
* @subelembuff_maxsize: Maximum size of subelembuff
* @is_fragseq: Pointer to location of a flag indicating whether this is a
* subelement fragment sequence or not. The flag will be set to true if the
* buffer contains a subelement fragment sequence starting with the subelement
* present in the beginning of the buffer, or the flag will be set to false if
* the buffer contains a single non-fragmented subelement in the beginning.
* Please note standards related limitation given in function description below.
* @fragseq_totallen: Pointer to location of total length of subelement fragment
* sequence. If is_fragseq is true, then this is set to the total length of the
* subelement fragment sequence, inclusive of the header and payload of the
* leading subelement and the headers and payloads of all subsequent fragments
* applicable to that subelement. If is_fragseq is false, the caller should
* ignore this. Please note standards related limitation given in function
* description below.
* @fragseq_payloadlen: Pointer to location of length of payload of subelement
* fragment sequence. If is_fragseq is true, then this length is set to the
* total size of the subelement fragment sequence payload, which does not
* include the sizes of the headers of the lead subelement and subsequent
* fragments. If is_fragseq is false, the caller should ignore this. Please note
* standards related limitation given in function description below.
*
* Get the following information for a first subelement present in the beginning
* of a given buffer, and a series of subelements after it in the given buffer:
* a) Whether a contiguous subset of these subelements starting with the first
* subelement form a subelement fragment sequence. b) If they form a subelement
* fragment sequence, then the total length of this sequence inclusive of
* headers and payloads of all the subelements in the sequence. c) If they form
* a subelement fragment sequence, then the total size of the payloads of all
* the subelements in the sequence. While determining this information, the
* function may return errors, including for protocol parsing issues. These
* protocol parsing issues include one in which the first subelement has a
* length lesser than 255, but the very next subelement after it is a fragment
* subelement (which is not allowed by the standard so far). Separately, please
* note a limitation arising from the standard wherein if the caller passes a
* truncated maximum buffer size such that the buffer ends prematurely just at
* the end of a potential lead subelement with length 255 or just at the end of
* a non-lead fragment subelement with length 255, the function will have to
* conclude that the last successfully parsed subelement is the final one in the
* non-fragment or fragment sequence, and return results accordingly. If another
* fragment actually exists beyond the given buffer, this function cannot detect
* the condition since there is no provision in the standard to indicate a total
* fragment sequence size in one place in the beginning or anywhere else. Hence
* the caller should take care to provide the complete buffer with the max size
* set accordingly.
*
* Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
* the reason for error in the case of failure
*/
QDF_STATUS wlan_get_subelem_fragseq_info(uint8_t subelemfragid,
uint8_t *subelembuff,
qdf_size_t subelembuff_maxsize,
bool *is_fragseq,
qdf_size_t *fragseq_totallen,
qdf_size_t *fragseq_payloadlen);
/**
* wlan_defrag_subelem_fragseq() - Defragment sequence of subelement fragments
*
* @inline_defrag: Whether to use inline defragmentation, wherein the
* defragmentation is carried out inline within the source buffer and no
* memmoves/memcopy would be required for the lead subelement.
* @subelemfragid: Fragment ID applicable for the subelement (this can
* potentially vary across protocol areas)
* @fragbuff: Source buffer containing the subelement fragment sequence starting
* with the subelement ID of the lead subelement. The containing element is
* required to have already been defragmented (if applicable). If inline
* defragmentation is enabled, the corresponding defragmented payload will be
* generated inline into this buffer and the defragmented payload will start
* after the location of the lead subelement's subelement ID and subelement
* length. This defragmented payload will not contain the headers of any of the
* other fragments in the fragment sequence.
* @fragbuff_maxsize: Maximum size of fragbuff. This should be greater than or
* equal to the total size of the subelement fragment sequence, inclusive of the
* header and payload of the leading subelement and the headers and payloads of
* all subsequent fragments applicable to that subelement.
* @defragbuff: The destination buffer into which the defragmented payload
* should be copied. This is inapplicable and ignored if inline_defrag is true.
* The defragmented payload will be copied to the start of the destination
* buffer without including the headers of the lead subelement and the
* subsequent fragment subelements.
* @defragbuff_maxsize: Maximum size of defragbuff. This is inapplicable and
* ignored if inline_defrag is true. The size should be large enough to contain
* the entire defragmented payload, otherwise an error will be returned.
* @defragpayload_len: Pointer to the location where the length of the
* defragmented payload should be updated. Irrespective of whether inline_defrag
* is true or false, this will not include the sizes of the headers of the lead
* subelement and subsequent fragments. Please note standards related limitation
* given in function description below.
*
* Defragment a sequence of subelement fragments. If the source buffer does not
* contain a subelement fragment sequence (in the beginning), the function
* returns an error. The containing element is required to have already been
* defragmented. An inline mode is available to carry out the defragmentation
* within the source buffer in order to reduce buffer requirements and to
* eliminate memory copies/moves for the lead subelement. In the inline mode,
* the buffer content (if any) after the fragments is moved as well. The
* contents of the defragmented payload are intended for end consumption by
* control path protocol processing code within the driver in a manner uniform
* with other protocol data in byte buffers, and not for onward forwarding to
* other subsystems or for intrusive specialized processing different from other
* protocol data. Hence zero copy methods such as network buffer fragment
* processing, etc. are not used in this use case. Additionally, this API is
* intended for use cases where the nature of the payload is complex and it is
* infeasible for the caller to skip the (un-defragmented) fragment boundaries
* on its own in a scalable and maintainable manner. Separately, please note a
* limitation arising from the standard wherein if the caller passes a truncated
* maximum buffer size such that the buffer ends prematurely just at the end of
* a fragment subelement with length 255, the function will have to conclude
* that the last successfully parsed fragment subelement is the final one in the
* fragment sequence, and return results accordingly. If another fragment
* actually exists beyond the given buffer, this function cannot detect the
* condition since there is no provision in the standard to indicate a total
* fragment sequence size in one place in the beginning or anywhere else. Hence
* the caller should take care to provide the complete buffer with the max size
* set accordingly.
*
* Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
* the reason for error in the case of failure
*/
QDF_STATUS wlan_defrag_subelem_fragseq(bool inline_defrag,
uint8_t subelemfragid,
uint8_t *fragbuff,
qdf_size_t fragbuff_maxsize,
uint8_t *defragbuff,
qdf_size_t defragbuff_maxsize,
qdf_size_t *defragpayload_len);
/**
* wlan_is_emulation_platform() - check if platform is emulation based
* @phy_version: psoc nif phy_version
*
* Return: boolean value based on platform type
*/
bool wlan_is_emulation_platform(uint32_t phy_version);
/**
* wlan_get_pdev_id_from_vdev_id() - Helper func to derive pdev id from vdev_id
* @psoc: psoc object
* @vdev_id: vdev identifier
* @dbg_id: object manager debug id
*
* This function is used to derive the pdev id from vdev id for a psoc
*
* Return : pdev_id - +ve integer for success and WLAN_INVALID_PDEV_ID
* for failure
*/
uint32_t wlan_get_pdev_id_from_vdev_id(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id,
wlan_objmgr_ref_dbgid dbg_id);
/**
* wlan_util_is_vdev_active() - Check for vdev active
* @pdev: pdev pointer
* @dbg_id: debug id for ref counting
*
* Return: QDF_STATUS_SUCCESS in case of vdev active
* QDF_STATUS_E_INVAL, if dev is not active
*/
QDF_STATUS wlan_util_is_vdev_active(struct wlan_objmgr_pdev *pdev,
wlan_objmgr_ref_dbgid dbg_id);
/**
* wlan_vdev_is_up() - Check for vdev is in UP state
* @vdev: vdev pointer
*
* Return: QDF_STATUS_SUCCESS, if vdev is in up, otherwise QDF_STATUS_E_FAILURE
*/
QDF_STATUS wlan_vdev_is_up(struct wlan_objmgr_vdev *vdev);
/**
* wlan_util_pdev_vdevs_deschan_match() - function to check des channel matches
* with other vdevs in pdev
* @pdev: pdev object
* @vdev: vdev object
* @dbg_id: object manager ref id
*
* This function checks the vdev desired channel with other vdev channels
*
* Return: QDF_STATUS_SUCCESS, if it matches, otherwise QDF_STATUS_E_FAILURE
*/
QDF_STATUS wlan_util_pdev_vdevs_deschan_match(struct wlan_objmgr_pdev *pdev,
struct wlan_objmgr_vdev *vdev,
wlan_objmgr_ref_dbgid dbg_id);
/**
* wlan_util_change_map_index() - function to set/reset given index bit
* @map: bitmpap
* @id: bit index
* @set: 1 for set, 0 of reset
*
* This function set/reset given index bit
*
* Return: void
*/
void wlan_util_change_map_index(unsigned long *map, uint8_t id, uint8_t set);
/**
* wlan_util_map_index_is_set() - function to check whether given index bit is
* set
* @map: bitmpap
* @id: bit index
*
* This function checks the given index bit is set
*
* Return: true, if bit is set, otherwise false
*/
bool wlan_util_map_index_is_set(unsigned long *map, uint8_t id);
/**
* wlan_util_map_is_any_index_set() - Check if any bit is set in given bitmap
* @map: bitmap
* @nbytes: number of bytes in bitmap
*
* Return: true, if any of the bit is set, otherwise false
*/
bool wlan_util_map_is_any_index_set(unsigned long *map, unsigned long nbytes);
/**
* wlan_pdev_chan_change_pending_vdevs() - function to test/set channel change
* pending flag
* @pdev: pdev object
* @vdev_id_map: bitmap to derive channel change vdevs
* @dbg_id: object manager ref id
*
* This function test/set channel change pending flag
*
* Return: QDF_STATUS_SUCCESS, if it iterates through all vdevs,
* otherwise QDF_STATUS_E_FAILURE
*/
QDF_STATUS wlan_pdev_chan_change_pending_vdevs(struct wlan_objmgr_pdev *pdev,
unsigned long *vdev_id_map,
wlan_objmgr_ref_dbgid dbg_id);
/**
* wlan_pdev_chan_change_pending_vdevs_down() - function to test/set down
* change pending flag
* @pdev: pdev object
* @vdev_id_map: bitmap to derive channel change vdevs
* @dbg_id: object manager ref id
*
* This function test/set channel change pending flag
*
* Return: QDF_STATUS_SUCCESS, if it iterates through all vdevs,
* otherwise QDF_STATUS_E_FAILURE
*/
QDF_STATUS wlan_pdev_chan_change_pending_vdevs_down(
struct wlan_objmgr_pdev *pdev,
unsigned long *vdev_id_map,
wlan_objmgr_ref_dbgid dbg_id);
/**
* wlan_pdev_chan_change_pending_ap_vdevs_down() - function to test/set channel
* change pending flag for AP VDEVs
* @pdev: pdev object
* @vdev_id_map: bitmap to derive channel change AP vdevs
* @dbg_id: object manager ref id
*
* This function test/set channel change pending flag for AP vdevs
*
* Return: QDF_STATUS_SUCCESS, if it iterates through all vdevs,
* otherwise QDF_STATUS_E_FAILURE
*/
QDF_STATUS wlan_pdev_chan_change_pending_ap_vdevs_down(
struct wlan_objmgr_pdev *pdev,
unsigned long *vdev_id_map,
wlan_objmgr_ref_dbgid dbg_id);
/**
* wlan_chan_eq() - function to check whether both channels are same
* @chan1: channel1 object
* @chan2: channel2 object
*
* This function checks the chan1 and chan2 are same
*
* Return: QDF_STATUS_SUCCESS, if it matches, otherwise QDF_STATUS_E_FAILURE
*/
QDF_STATUS wlan_chan_eq(struct wlan_channel *chan1, struct wlan_channel *chan2);
/**
* wlan_chan_copy() - function to copy channel
* @tgt: target channel object
* @src: src achannel object
*
* This function copies channel data from src to tgt
*
* Return: void
*/
void wlan_chan_copy(struct wlan_channel *tgt, struct wlan_channel *src);
/**
* wlan_vdev_get_active_channel() - derives the vdev operating channel
* @vdev: VDEV object
*
* This function checks vdev state and return the channel pointer accordingly
*
* Return: active channel, if vdev chan config is valid
* NULL, if VDEV is in INIT or STOP state
*/
struct wlan_channel *wlan_vdev_get_active_channel
(struct wlan_objmgr_vdev *vdev);
/**
* wlan_get_connected_vdev_by_bssid() - check/get any vdev connected on bssid
* @pdev: pdev object
* @bssid: bssid to be checked
* @vdev_id: vdev id
*
* This function will loop through all the vdev in psoc and find/return the
* vdev which is connected to bssid provided.
*
* Return: bool
*/
bool wlan_get_connected_vdev_by_bssid(struct wlan_objmgr_pdev *pdev,
uint8_t *bssid, uint8_t *vdev_id);
/**
* wlan_get_connected_vdev_from_psoc_by_bssid() - check/get any vdev
* connected on bssid
* @psoc: psoc object
* @bssid: bssid to be checked
* @vdev_id: vdev id
*
* This function will loop through all the vdev in psoc and find/return the
* vdev which is connected to bssid provided.
*
* Return: bool
*/
bool wlan_get_connected_vdev_from_psoc_by_bssid(struct wlan_objmgr_psoc *psoc,
uint8_t *bssid,
uint8_t *vdev_id);
#ifdef WLAN_FEATURE_11BE_MLO
/**
* wlan_get_connected_vdev_by_mld_addr() - check/get any vdev
* connected on mld mac
* @psoc: psoc object
* @mld_mac: mld mac to be checked
* @vdev_id: vdev id
*
* This function will loop through all the vdev in psoc and find/return the
* first vdev which is connected to mld mac provided.
*
* Return: bool
*/
bool wlan_get_connected_vdev_by_mld_addr(struct wlan_objmgr_psoc *psoc,
uint8_t *mld_mac, uint8_t *vdev_id);
#endif
/**
* wlan_util_stats_get_rssi() - API to get rssi in dbm
* @db2dbm_enabled: If db2dbm capability is enabled
* @bcn_snr: beacon snr
* @dat_snr: data snr
* @rssi: rssi
*
* This function gets the rssi based on db2dbm support. If this feature is
* present in hw then it means firmware directly sends rssi and no conversion
* is required. If this capability is not present then host needs to convert
* snr to rssi
*
* Return: None
*/
void
wlan_util_stats_get_rssi(bool db2dbm_enabled, int32_t bcn_snr, int32_t dat_snr,
int8_t *rssi);
/**
* wlan_util_is_pdev_restart_progress() - Check if any vdev is in restart state
* @pdev: pdev pointer
* @dbg_id: module id
*
* Iterates through all vdevs, checks if any VDEV is in RESTART_PROGRESS
* substate
*
* Return: QDF_STATUS_SUCCESS,if any vdev is in RESTART_PROGRESS substate
* otherwise QDF_STATUS_E_FAILURE
*/
QDF_STATUS wlan_util_is_pdev_restart_progress(struct wlan_objmgr_pdev *pdev,
wlan_objmgr_ref_dbgid dbg_id);
/**
* wlan_util_is_pdev_scan_allowed() - Check for vdev is allowed to scan
* @pdev: pdev pointer
* @dbg_id: module id
*
* Iterates through all vdevs, checks if any VDEV is not either in S_INIT or in
* S_UP state
*
* Return: QDF_STATUS_SUCCESS,if scan is allowed, otherwise QDF_STATUS_E_FAILURE
*/
QDF_STATUS wlan_util_is_pdev_scan_allowed(struct wlan_objmgr_pdev *pdev,
wlan_objmgr_ref_dbgid dbg_id);
/**
* wlan_util_get_peer_count_for_mode - This api gives vdev mode specific
* peer count`
* @pdev: PDEV object
* @mode: Operation mode.
*
* Return: int- peer count for operating mode
*/
uint16_t wlan_util_get_peer_count_for_mode(struct wlan_objmgr_pdev *pdev,
enum QDF_OPMODE mode);
/**
* enum wlan_minidump_host_data - Data structure type logged in Minidump
* @WLAN_MD_CP_EXT_PDEV: ol_ath_softc_net80211
* @WLAN_MD_CP_EXT_PSOC: ol_ath_soc_softc
* @WLAN_MD_CP_EXT_VDEV: ieee80211vap
* @WLAN_MD_CP_EXT_PEER: ieee80211_node
* @WLAN_MD_DP_SOC: dp_soc
* @WLAN_MD_DP_PDEV: dp_pdev
* @WLAN_MD_DP_VDEV: dp_vdev
* @WLAN_MD_DP_PEER: dp_peer
* @WLAN_MD_DP_SRNG_REO_DEST: dp_srng type for reo dest
* @WLAN_MD_DP_SRNG_REO_EXCEPTION: dp_srng type for reo exception
* @WLAN_MD_DP_SRNG_REO_CMD: dp_srng type for reo cmd
* @WLAN_MD_DP_SRNG_RX_REL: dp_srng type for reo release
* @WLAN_MD_DP_SRNG_REO_REINJECT: dp_srng type for reo reinject
* @WLAN_MD_DP_SRNG_REO_STATUS: dp_srng type for reo status
* @WLAN_MD_DP_SRNG_TCL_DATA: dp_srng type for tcl data
* @WLAN_MD_DP_SRNG_TCL_CMD: dp_srng type for tcl cmd
* @WLAN_MD_DP_SRNG_TCL_STATUS: dp_srng type for tcl status
* @WLAN_MD_DP_SRNG_TX_COMP: dp_srng type for tcl comp
* @WLAN_MD_DP_SRNG_WBM_DESC_REL: dp_srng_type for wbm desc rel
* @WLAN_MD_DP_SRNG_WBM_IDLE_LINK: dp_srng type for wbm idle link
* @WLAN_MD_DP_LINK_DESC_BANK: Wbm link_desc_bank
* @WLAN_MD_DP_SRNG_RXDMA_MON_STATUS: dp_srng type for rxdma mon status
* @WLAN_MD_DP_SRNG_RXDMA_MON_BUF: dp_srng type for rxdma mon buf
* @WLAN_MD_DP_SRNG_RXDMA_MON_DST: dp_srng type for rxdma mon dest
* @WLAN_MD_DP_SRNG_RXDMA_MON_DESC: dp_srng type for rxdma mon desc
* @WLAN_MD_DP_SRNG_RXDMA_ERR_DST: dp_srng type for rxdma err dst
* @WLAN_MD_DP_HAL_SOC: hal_soc
* @WLAN_MD_OBJMGR_PSOC: wlan_objmgr_psoc
* @WLAN_MD_OBJMGR_PSOC_TGT_INFO: wlan_objmgr_tgt_psoc_info
* @WLAN_MD_OBJMGR_PDEV: wlan_objmgr_pdev
* @WLAN_MD_OBJMGR_PDEV_MLME: pdev_mlme
* @WLAN_MD_OBJMGR_VDEV: wlan_objmgr_vdev
* @WLAN_MD_OBJMGR_VDEV_MLME: vdev mlme
* @WLAN_MD_OBJMGR_VDEV_SM: wlan_sm
* @WLAN_MD_DP_SRNG_REO2PPE: dp_srng type PPE rx ring
* @WLAN_MD_DP_SRNG_PPE2TCL: dp_srng type for PPE tx ring
* @WLAN_MD_DP_SRNG_PPE_RELEASE: dp_srng type for PPE tx com ring
* @WLAN_MD_DP_SRNG_PPE_WBM2SW_RELEASE: dp_srng type for PPE2TCL tx com ring
* @WLAN_MD_DP_SRNG_SW2RXDMA_LINK_RING: dp_srng type for SW2RXDMA link ring
* @WLAN_MD_MAX: Max value
*/
enum wlan_minidump_host_data {
WLAN_MD_CP_EXT_PDEV,
WLAN_MD_CP_EXT_PSOC,
WLAN_MD_CP_EXT_VDEV,
WLAN_MD_CP_EXT_PEER,
WLAN_MD_DP_SOC,
WLAN_MD_DP_PDEV,
WLAN_MD_DP_VDEV,
WLAN_MD_DP_PEER,
WLAN_MD_DP_SRNG_REO_DEST,
WLAN_MD_DP_SRNG_REO_EXCEPTION,
WLAN_MD_DP_SRNG_REO_CMD,
WLAN_MD_DP_SRNG_RX_REL,
WLAN_MD_DP_SRNG_REO_REINJECT,
WLAN_MD_DP_SRNG_REO_STATUS,
WLAN_MD_DP_SRNG_TCL_DATA,
WLAN_MD_DP_SRNG_TCL_CMD,
WLAN_MD_DP_SRNG_TCL_STATUS,
WLAN_MD_DP_SRNG_TX_COMP,
WLAN_MD_DP_SRNG_WBM_DESC_REL,
WLAN_MD_DP_SRNG_WBM_IDLE_LINK,
WLAN_MD_DP_LINK_DESC_BANK,
WLAN_MD_DP_SRNG_RXDMA_MON_STATUS,
WLAN_MD_DP_SRNG_RXDMA_MON_BUF,
WLAN_MD_DP_SRNG_RXDMA_MON_DST,
WLAN_MD_DP_SRNG_RXDMA_MON_DESC,
WLAN_MD_DP_SRNG_RXDMA_ERR_DST,
WLAN_MD_DP_HAL_SOC,
WLAN_MD_OBJMGR_PSOC,
WLAN_MD_OBJMGR_PSOC_TGT_INFO,
WLAN_MD_OBJMGR_PDEV,
WLAN_MD_OBJMGR_PDEV_MLME,
WLAN_MD_OBJMGR_VDEV,
WLAN_MD_OBJMGR_VDEV_MLME,
WLAN_MD_OBJMGR_VDEV_SM,
WLAN_MD_DP_SRNG_REO2PPE,
WLAN_MD_DP_SRNG_PPE2TCL,
WLAN_MD_DP_SRNG_PPE_RELEASE,
WLAN_MD_DP_SRNG_PPE_WBM2SW_RELEASE,
WLAN_MD_DP_SRNG_SW2RXDMA_LINK_RING,
WLAN_MD_MAX
};
/**
* wlan_minidump_log() - Log memory address to be included in minidump
* @start_addr: Start address of the memory to be dumped
* @size: Size in bytes
* @psoc_obj: Psoc Object
* @type: Type of data structure
* @name: String to identify this entry
*/
void wlan_minidump_log(void *start_addr, const size_t size,
void *psoc_obj,
enum wlan_minidump_host_data type,
const char *name);
/**
* wlan_minidump_remove() - Remove memory address from minidump
* @start_addr: Start address of the memory previously added
* @size: Size in bytes
* @psoc_obj: Psoc Object
* @type: Type of data structure
* @name: String to identify this entry
*/
void wlan_minidump_remove(void *start_addr, const size_t size,
void *psoc_obj,
enum wlan_minidump_host_data type,
const char *name);
/**
* wlan_util_is_vdev_in_cac_wait() - Check if dfs sap vdev is in cac wait
* @pdev: pdev object
* @dbg_id: object manager ref id
*
* This function checks if dfs sap vdev is in cac wait state
*
* Return: true, if cac is in progress, otherwise false
*/
bool wlan_util_is_vdev_in_cac_wait(struct wlan_objmgr_pdev *pdev,
wlan_objmgr_ref_dbgid dbg_id);
/**
* wlan_eht_chan_phy_mode - convert eht chan to phy mode
* @freq: frequency
* @bw_val: bandwidth
* @chan_width: channel width
*
* Return: return phy mode
*/
enum wlan_phymode
wlan_eht_chan_phy_mode(uint32_t freq,
uint16_t bw_val,
enum phy_ch_width chan_width);
#endif /* _WLAN_UTILITY_H_ */