qcacmn: Parse EML capability subfield in Common info for non-AP MLD

Parse EML capability sub field present in Common Info field of Basic
Multi-Link element from Association request send by non-AP MLD.

Add new API to get EML capabilities from the ML IE.
Update definitions for EML as per IEEE802.11be D1.5.
Store parsed EML capability in node to send these to Target.

CRs-Fixed: 3203322
Change-Id: Ib208ba2d8e86df7360656c1c844e4835a93cedc4
这个提交包含在:
Shreedhar Parande
2022-04-27 15:16:09 +05:30
提交者 Madan Koyyalamudi
父节点 3ebb459d03
当前提交 5f96fd74c9
修改 3 个文件,包含 157 行新增16 行删除

查看文件

@@ -162,6 +162,29 @@ QDF_STATUS
util_get_bvmlie_mldmacaddr(uint8_t *mlieseq, qdf_size_t mlieseqlen,
struct qdf_mac_addr *mldmacaddr);
/**
* util_get_bvmlie_eml_cap - Get the EML capabilities from a given Basic
* variant Multi-Link element or element fragment sequence.
* @mlieseq: Starting address of the Multi-Link element or Multi-Link element
* fragment sequence
* @mlieseqlen: Total length of the Multi-Link element or Multi-Link element
* fragment sequence
* @eml_cap_found: Pointer to the location where a boolean status should be
* updated indicating whether the EML cabalility was found or not. This should
* be ignored by the caller if the function returns error.
* @eml_cap: Pointer to the location where the EML capabilities should be
* updated.
* This should be ignored by the caller if the function indicates that the
* EML capability was not found.
*
* Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
* the reason for error in the case of failure
*/
QDF_STATUS
util_get_bvmlie_eml_cap(uint8_t *mlieseq, qdf_size_t mlieseqlen,
bool *eml_cap_found,
uint16_t *eml_cap);
/**
* util_get_bvmlie_primary_linkid - Get the link identifier from a given Basic
* variant Multi-Link element or element fragment sequence, of the AP that
@@ -343,6 +366,14 @@ util_get_bvmlie_mldmacaddr(uint8_t *mlieseq, qdf_size_t mlieseqlen,
return QDF_STATUS_E_NOSUPPORT;
}
static inline QDF_STATUS
util_get_bvmlie_eml_cap(uint8_t *mlieseq, qdf_size_t mlieseqlen,
bool *eml_cap_found,
uint16_t *eml_cap)
{
return QDF_STATUS_E_NOSUPPORT;
}
static inline QDF_STATUS
util_get_bvmlie_primary_linkid(uint8_t *mlieseq, qdf_size_t mlieseqlen,
bool *linkidfound, uint8_t *linkid)

查看文件

@@ -2313,6 +2313,90 @@ util_get_mlie_variant(uint8_t *mlieseq, qdf_size_t mlieseqlen,
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
util_get_bvmlie_eml_cap(uint8_t *mlieseq, qdf_size_t mlieseqlen,
bool *eml_cap_found,
uint16_t *eml_cap)
{
struct wlan_ie_multilink *mlie_fixed;
enum wlan_ml_variant variant;
uint16_t mlcontrol;
uint8_t eml_cap_offset;
uint8_t commoninfo_len;
uint16_t presencebitmap;
if (!mlieseq || !mlieseqlen || !eml_cap_found || !eml_cap)
return QDF_STATUS_E_NULL_VALUE;
*eml_cap = 0;
*eml_cap_found = false;
if (mlieseqlen < sizeof(struct wlan_ie_multilink))
return QDF_STATUS_E_INVAL;
mlie_fixed = (struct wlan_ie_multilink *)mlieseq;
if ((mlie_fixed->elem_id != WLAN_ELEMID_EXTN_ELEM) ||
(mlie_fixed->elem_id_ext != WLAN_EXTN_ELEMID_MULTI_LINK))
return QDF_STATUS_E_INVAL;
mlcontrol = qdf_le16_to_cpu(mlie_fixed->mlcontrol);
variant = QDF_GET_BITS(mlcontrol, WLAN_ML_CTRL_TYPE_IDX,
WLAN_ML_CTRL_TYPE_BITS);
if (variant != WLAN_ML_VARIANT_BASIC)
return QDF_STATUS_E_INVAL;
presencebitmap = QDF_GET_BITS(mlcontrol, WLAN_ML_CTRL_PBM_IDX,
WLAN_ML_CTRL_PBM_BITS);
/* eml_cap_offset stores the offset of EML Capabilities within
* Common Info
*/
eml_cap_offset = WLAN_ML_BV_CINFO_LENGTH_SIZE + QDF_MAC_ADDR_SIZE;
if (presencebitmap & WLAN_ML_BV_CTRL_PBM_LINKIDINFO_P)
eml_cap_offset += WLAN_ML_BV_CINFO_LINKIDINFO_SIZE;
if (presencebitmap & WLAN_ML_BV_CTRL_PBM_BSSPARAMCHANGECNT_P)
eml_cap_offset += WLAN_ML_BV_CINFO_BSSPARAMCHNGCNT_SIZE;
if (presencebitmap & WLAN_ML_BV_CTRL_PBM_MEDIUMSYNCDELAYINFO_P)
eml_cap_offset += WLAN_ML_BV_CINFO_MEDMSYNCDELAYINFO_SIZE;
if (presencebitmap & WLAN_ML_BV_CTRL_PBM_EMLCAP_P) {
/* Common Info starts at
* mlieseq + sizeof(struct wlan_ie_multilink).
* Check if there is sufficient space in the buffer for
* the Common Info Length.
*/
if (mlieseqlen < (sizeof(struct wlan_ie_multilink) +
WLAN_ML_BV_CINFO_LENGTH_SIZE))
return QDF_STATUS_E_PROTO;
/* Check if the value indicated in the Common Info Length
* subfield is sufficient to access the EML capabilities.
*/
commoninfo_len = *(mlieseq + sizeof(struct wlan_ie_multilink));
if (commoninfo_len < (eml_cap_offset +
WLAN_ML_BV_CINFO_EMLCAP_SIZE))
return QDF_STATUS_E_PROTO;
/* Common Info starts at mlieseq + sizeof(struct
* wlan_ie_multilink). Check if there is sufficient space in
* Common Info for the EML capability.
*/
if (mlieseqlen < (sizeof(struct wlan_ie_multilink) +
eml_cap_offset +
WLAN_ML_BV_CINFO_EMLCAP_SIZE))
return QDF_STATUS_E_PROTO;
*eml_cap_found = true;
*eml_cap = qdf_le16_to_cpu(*(uint16_t *)(mlieseq +
sizeof(struct wlan_ie_multilink) +
eml_cap_offset));
}
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
util_get_bvmlie_mldmacaddr(uint8_t *mlieseq, qdf_size_t mlieseqlen,
struct qdf_mac_addr *mldmacaddr)