qcacmn: Update multilink reconfig ie for ieee802.11be D 3.0

Update ML Reconfig ie parsing for D 3.0:
1.Add new common info length subfield in common info length.
2.remove STA profile subfield from Per-STA profile subelement
3.add STA info length and STA mac address subfields in the
STA info field.

Change-Id: I02988ae7a2098b0278438e26156475e2b4f9c4ab
CRs-Fixed: 3465406
This commit is contained in:
Liangwei Dong
2023-01-06 11:34:25 +08:00
committad av Rahul Choudhary
förälder aebcc2ee76
incheckning d430e6a706
4 ändrade filer med 166 tillägg och 47 borttagningar

Visa fil

@@ -480,6 +480,7 @@ util_get_prvmlie_persta_link_id(uint8_t *mlieseq,
* fragment sequence
* @mldmacaddr: Pointer to the location where the MLD MAC address should be
* updated. This should be ignored by the caller if the function returns error.
* @is_mldmacaddr_found: mld address found or not
*
* Get the MLD MAC address from a given Reconfig variant Multi-Link element
* or element fragment sequence.
@@ -489,7 +490,8 @@ util_get_prvmlie_persta_link_id(uint8_t *mlieseq,
*/
QDF_STATUS
util_get_rvmlie_mldmacaddr(uint8_t *mlieseq, qdf_size_t mlieseqlen,
struct qdf_mac_addr *mldmacaddr);
struct qdf_mac_addr *mldmacaddr,
bool *is_mldmacaddr_found);
/**
* util_get_rvmlie_persta_link_info() - Get per-STA reconfig link information
@@ -629,7 +631,8 @@ util_get_prvmlie_mldid(uint8_t *mlieseq, qdf_size_t mlieseqlen,
static inline QDF_STATUS
util_get_rvmlie_mldmacaddr(uint8_t *mlieseq, qdf_size_t mlieseqlen,
struct qdf_mac_addr *mldmacaddr)
struct qdf_mac_addr *mldmacaddr,
bool *is_mldmacaddr_found)
{
return QDF_STATUS_E_NOSUPPORT;
}

Visa fil

@@ -728,13 +728,15 @@ struct mlo_probereq_info {
/**
* struct ml_rv_partner_link_info: Partner link information of an ML reconfig IE
* @link_id: Link id advertised by the AP
* @is_delete_timer_p: Delete timer is present or not
* @delete_timer: number of TBTTs of the AP
* @link_mac_addr: Link mac address
* @is_ap_removal_timer_p: AP removal timer is present or not
* @ap_removal_timer: number of TBTTs of the AP removal timer
*/
struct ml_rv_partner_link_info {
uint8_t link_id;
uint8_t is_delete_timer_p;
uint16_t delete_timer;
struct qdf_mac_addr link_mac_addr;
uint8_t is_ap_removal_timer_p;
uint16_t ap_removal_timer;
};
/**

Visa fil

@@ -3999,16 +3999,19 @@ util_get_prvmlie_mldid(uint8_t *mlieseq, qdf_size_t mlieseqlen,
}
QDF_STATUS util_get_rvmlie_mldmacaddr(uint8_t *mlieseq, qdf_size_t mlieseqlen,
struct qdf_mac_addr *mldmacaddr)
struct qdf_mac_addr *mldmacaddr,
bool *is_mldmacaddr_found)
{
struct wlan_ie_multilink *mlie_fixed;
enum wlan_ml_variant variant;
uint16_t mlcontrol;
uint16_t presencebitmap;
qdf_size_t rv_cinfo_len;
if (!mlieseq || !mlieseqlen || !mldmacaddr)
if (!mlieseq || !mlieseqlen || !mldmacaddr || !is_mldmacaddr_found)
return QDF_STATUS_E_NULL_VALUE;
*is_mldmacaddr_found = false;
qdf_mem_zero(mldmacaddr, sizeof(*mldmacaddr));
if (mlieseqlen < sizeof(struct wlan_ie_multilink))
@@ -4028,18 +4031,35 @@ QDF_STATUS util_get_rvmlie_mldmacaddr(uint8_t *mlieseq, qdf_size_t mlieseqlen,
if (variant != WLAN_ML_VARIANT_RECONFIG)
return QDF_STATUS_E_INVAL;
/* ML Reconfig Common Info Length field present */
if ((sizeof(struct wlan_ie_multilink) + WLAN_ML_RV_CINFO_LENGTH_SIZE) >
mlieseqlen)
return QDF_STATUS_E_PROTO;
rv_cinfo_len = *(mlieseq + sizeof(struct wlan_ie_multilink));
presencebitmap = QDF_GET_BITS(mlcontrol, WLAN_ML_CTRL_PBM_IDX,
WLAN_ML_CTRL_PBM_BITS);
/* Check if MLD mac address is present */
if (presencebitmap & WLAN_ML_RV_CTRL_PBM_MLDMACADDR_P) {
if ((sizeof(struct wlan_ie_multilink) + QDF_MAC_ADDR_SIZE) >
/* Check if the value indicated in the Common Info Length
* subfield is sufficient to access the MLD MAC address.
*/
if (rv_cinfo_len < (WLAN_ML_RV_CINFO_LENGTH_SIZE +
QDF_MAC_ADDR_SIZE))
return QDF_STATUS_E_PROTO;
if ((sizeof(struct wlan_ie_multilink) +
WLAN_ML_RV_CINFO_LENGTH_SIZE + QDF_MAC_ADDR_SIZE) >
mlieseqlen)
return QDF_STATUS_E_PROTO;
qdf_mem_copy(mldmacaddr->bytes,
mlieseq + sizeof(struct wlan_ie_multilink),
mlieseq + sizeof(struct wlan_ie_multilink) +
WLAN_ML_RV_CINFO_LENGTH_SIZE,
QDF_MAC_ADDR_SIZE);
*is_mldmacaddr_found = true;
}
return QDF_STATUS_SUCCESS;
@@ -4051,7 +4071,7 @@ util_parse_rv_multi_link_ctrl(uint8_t *mlieseqpayload,
uint8_t **link_info,
qdf_size_t *link_info_len)
{
qdf_size_t parsed_payload_len;
qdf_size_t parsed_payload_len, rv_cinfo_len;
uint16_t mlcontrol;
uint16_t presence_bm;
@@ -4089,17 +4109,43 @@ util_parse_rv_multi_link_ctrl(uint8_t *mlieseqpayload,
mlcontrol = qdf_le16_to_cpu(mlcontrol);
parsed_payload_len += WLAN_ML_CTRL_SIZE;
if (mlieseqpayloadlen <
(parsed_payload_len + WLAN_ML_RV_CINFO_LENGTH_SIZE)) {
mlo_err_rl("ML rv seq payload len %zu insufficient for common info length size %u after parsed payload len %zu.",
mlieseqpayloadlen,
WLAN_ML_RV_CINFO_LENGTH_SIZE,
parsed_payload_len);
return QDF_STATUS_E_PROTO;
}
rv_cinfo_len = *(mlieseqpayload + parsed_payload_len);
parsed_payload_len += WLAN_ML_RV_CINFO_LENGTH_SIZE;
presence_bm = QDF_GET_BITS(mlcontrol, WLAN_ML_CTRL_PBM_IDX,
WLAN_ML_CTRL_PBM_BITS);
/* Check if MLD MAC address is present */
if (presence_bm & WLAN_ML_RV_CTRL_PBM_MLDMACADDR_P) {
/* Check if the value indicated in the Common Info Length
* subfield is sufficient to access the MLD MAC address.
* Note: In D3.0, MLD MAC address will not be present
* in ML Reconfig IE. But for code completeness, we
* should have below code to sanity check.
*/
if (rv_cinfo_len < (WLAN_ML_RV_CINFO_LENGTH_SIZE +
QDF_MAC_ADDR_SIZE)) {
mlo_err_rl("ML rv Common Info Length %zu insufficient to access MLD MAC addr size %u.",
rv_cinfo_len,
QDF_MAC_ADDR_SIZE);
return QDF_STATUS_E_PROTO;
}
if (mlieseqpayloadlen <
(parsed_payload_len +
QDF_MAC_ADDR_SIZE)) {
mlo_err_rl("ML seq payload len %zu insufficient for MLD ID size %u after parsed payload len %zu.",
mlo_err_rl("ML seq payload len %zu insufficient for MLD MAC size %u after parsed payload len %zu.",
mlieseqpayloadlen,
WLAN_ML_PRV_CINFO_MLDID_SIZE,
QDF_MAC_ADDR_SIZE,
parsed_payload_len);
return QDF_STATUS_E_PROTO;
}
@@ -4107,10 +4153,31 @@ util_parse_rv_multi_link_ctrl(uint8_t *mlieseqpayload,
parsed_payload_len += QDF_MAC_ADDR_SIZE;
}
/* At present, we only handle MAC address field in common info field.
* To be compatible with future spec updating, if new items are added
* to common info, below log will highlight the spec change.
*/
if (rv_cinfo_len != (parsed_payload_len - WLAN_ML_CTRL_SIZE))
mlo_debug_rl("ML rv seq common info len %zu doesn't match with expected common info len %zu",
rv_cinfo_len,
parsed_payload_len - WLAN_ML_CTRL_SIZE);
if (mlieseqpayloadlen < (WLAN_ML_CTRL_SIZE + rv_cinfo_len)) {
mlo_err_rl("ML seq payload len %zu insufficient for rv link info after parsed mutli-link control %u and indicated Common Info length %zu",
mlieseqpayloadlen,
WLAN_ML_CTRL_SIZE,
rv_cinfo_len);
return QDF_STATUS_E_PROTO;
}
/* Update parsed_payload_len to reflect the actual bytes in common info
* field to be compatible with future spec updating.
*/
parsed_payload_len = WLAN_ML_CTRL_SIZE + rv_cinfo_len;
if (link_info_len) {
*link_info_len = mlieseqpayloadlen - parsed_payload_len;
mlo_debug("link_info_len:%zu, parsed_payload_len:%zu",
*link_info_len, parsed_payload_len);
mlo_debug("link_info_len:%zu, parsed_payload_len:%zu, rv_cinfo_len %zu ",
*link_info_len, parsed_payload_len, rv_cinfo_len);
}
if (mlieseqpayloadlen == parsed_payload_len) {
@@ -4133,10 +4200,11 @@ util_parse_rvmlie_perstaprofile_stactrl(uint8_t *subelempayload,
uint8_t *linkid,
bool *is_macaddr_valid,
struct qdf_mac_addr *macaddr,
bool *is_delete_timer_valid,
uint16_t *delete_timer)
bool *is_ap_removal_timer_valid,
uint16_t *ap_removal_timer)
{
qdf_size_t parsed_payload_len = 0;
qdf_size_t parsed_payload_len = 0, sta_info_len;
qdf_size_t parsed_sta_info_len;
uint16_t stacontrol;
uint8_t completeprofile;
@@ -4189,11 +4257,29 @@ util_parse_rvmlie_perstaprofile_stactrl(uint8_t *subelempayload,
if (is_macaddr_valid)
*is_macaddr_valid = false;
if (subelempayloadlen < parsed_payload_len +
WLAN_ML_RV_LINFO_PERSTAPROF_STAINFO_LENGTH_SIZE) {
mlo_err_rl("Length of subelement payload %zu octets not sufficient for sta info length of size %u octets after parsed payload length of %zu octets.",
subelempayloadlen, WLAN_ML_RV_LINFO_PERSTAPROF_STAINFO_LENGTH_SIZE,
parsed_payload_len);
return QDF_STATUS_E_PROTO;
}
sta_info_len = *(subelempayload + parsed_payload_len);
parsed_payload_len += WLAN_ML_RV_LINFO_PERSTAPROF_STAINFO_LENGTH_SIZE;
parsed_sta_info_len = WLAN_ML_RV_LINFO_PERSTAPROF_STAINFO_LENGTH_SIZE;
/* Check STA MAC address present bit */
if (QDF_GET_BITS(stacontrol,
WLAN_ML_RV_LINFO_PERSTAPROF_STACTRL_MACADDRP_IDX,
WLAN_ML_RV_LINFO_PERSTAPROF_STACTRL_MACADDRP_BITS)) {
WLAN_ML_RV_LINFO_PERSTAPROF_STACTRL_STAMACADDRP_IDX,
WLAN_ML_RV_LINFO_PERSTAPROF_STACTRL_STAMACADDRP_BITS)) {
if (sta_info_len < (parsed_sta_info_len + QDF_MAC_ADDR_SIZE)) {
mlo_err_rl("Length of sta info len %zu octets not sufficient to contain MAC address of size %u octets after parsed sta info length of %zu octets.",
sta_info_len, QDF_MAC_ADDR_SIZE,
parsed_sta_info_len);
return QDF_STATUS_E_PROTO;
}
if (subelempayloadlen <
(parsed_payload_len + QDF_MAC_ADDR_SIZE)) {
mlo_err_rl("Length of subelement payload %zu octets not sufficient to contain MAC address of size %u octets after parsed payload length of %zu octets.",
@@ -4214,33 +4300,56 @@ util_parse_rvmlie_perstaprofile_stactrl(uint8_t *subelempayload,
}
parsed_payload_len += QDF_MAC_ADDR_SIZE;
parsed_sta_info_len += QDF_MAC_ADDR_SIZE;
}
/* Check Delete timer present bit */
/* Check AP Removal timer present bit */
if (QDF_GET_BITS(stacontrol,
WLAN_ML_RV_LINFO_PERSTAPROF_STACTRL_DELTIMERP_IDX,
WLAN_ML_RV_LINFO_PERSTAPROF_STACTRL_DELTIMERP_BITS)) {
WLAN_ML_RV_LINFO_PERSTAPROF_STACTRL_APREMOVALTIMERP_IDX,
WLAN_ML_RV_LINFO_PERSTAPROF_STACTRL_APREMOVALTIMERP_BITS)) {
if (sta_info_len <
(parsed_sta_info_len +
WLAN_ML_RV_LINFO_PERSTAPROF_STAINFO_APREMOVALTIMER_SIZE)) {
mlo_err_rl("Length of sta info len %zu octets not sufficient to contain AP removal timer of size %u octets after parsed sta info length of %zu octets.",
sta_info_len, WLAN_ML_RV_LINFO_PERSTAPROF_STAINFO_APREMOVALTIMER_SIZE,
parsed_sta_info_len);
return QDF_STATUS_E_PROTO;
}
if (subelempayloadlen <
(parsed_payload_len +
WLAN_ML_RV_LINFO_PERSTAPROF_STAINFO_DELTIMER_SIZE)) {
mlo_err_rl("Length of subelement payload %zu octets not sufficient to contain Delete timer of size %u octets after parsed payload length of %zu octets.",
WLAN_ML_RV_LINFO_PERSTAPROF_STAINFO_APREMOVALTIMER_SIZE)) {
mlo_err_rl("Length of subelement payload %zu octets not sufficient to contain AP removal timer of size %u octets after parsed payload length of %zu octets.",
subelempayloadlen,
WLAN_ML_RV_LINFO_PERSTAPROF_STAINFO_DELTIMER_SIZE,
WLAN_ML_RV_LINFO_PERSTAPROF_STAINFO_APREMOVALTIMER_SIZE,
parsed_payload_len);
return QDF_STATUS_E_PROTO;
}
if (delete_timer) {
qdf_mem_copy(delete_timer,
if (ap_removal_timer) {
qdf_mem_copy(ap_removal_timer,
subelempayload + parsed_payload_len,
WLAN_ML_RV_LINFO_PERSTAPROF_STAINFO_DELTIMER_SIZE);
WLAN_ML_RV_LINFO_PERSTAPROF_STAINFO_APREMOVALTIMER_SIZE);
if (is_delete_timer_valid)
*is_delete_timer_valid = true;
if (is_ap_removal_timer_valid)
*is_ap_removal_timer_valid = true;
}
parsed_payload_len += WLAN_ML_RV_LINFO_PERSTAPROF_STAINFO_DELTIMER_SIZE;
parsed_payload_len +=
WLAN_ML_RV_LINFO_PERSTAPROF_STAINFO_APREMOVALTIMER_SIZE;
parsed_sta_info_len += WLAN_ML_RV_LINFO_PERSTAPROF_STAINFO_APREMOVALTIMER_SIZE;
}
/* At present, we only handle link MAC address field and ap removal
* timer tbtt field parsing. To be compatible with future spec
* updating, if new items are added to sta info, below log will
* highlight the spec change.
*/
if (sta_info_len != (parsed_payload_len -
WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_SIZE))
mlo_debug_rl("Length of sta info len %zu octets not match parsed payload length of %zu octets.",
sta_info_len,
parsed_payload_len -
WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_SIZE);
return QDF_STATUS_SUCCESS;
}
@@ -4261,8 +4370,8 @@ util_parse_rv_info_from_linkinfo(uint8_t *linkinfo,
QDF_STATUS ret;
struct qdf_mac_addr mac_addr;
bool is_macaddr_valid;
bool is_delete_timer_valid;
uint16_t delete_timer;
bool is_ap_removal_timer_valid;
uint16_t ap_removal_timer;
/* This helper function parses probe request info from the per-STA prof
* present (if any) in the Link Info field in the payload of a Multi
@@ -4368,32 +4477,37 @@ util_parse_rv_info_from_linkinfo(uint8_t *linkinfo,
}
if (subelemid == WLAN_ML_LINFO_SUBELEMID_PERSTAPROFILE) {
struct ml_rv_partner_link_info *link_info;
is_macaddr_valid = false;
is_delete_timer_valid = false;
is_ap_removal_timer_valid = false;
ret = util_parse_rvmlie_perstaprofile_stactrl(linkinfo_currpos +
sizeof(struct subelem_header),
subelemseqpayloadlen,
&linkid,
&is_macaddr_valid,
&mac_addr,
&is_delete_timer_valid,
&delete_timer);
&is_ap_removal_timer_valid,
&ap_removal_timer);
if (QDF_IS_STATUS_ERROR(ret))
return ret;
link_info =
&reconfig_info->link_info[reconfig_info->num_links];
link_info->link_id = linkid;
link_info->is_ap_removal_timer_p = is_ap_removal_timer_valid;
if (is_macaddr_valid)
qdf_copy_macaddr(&link_info->link_mac_addr,
&mac_addr);
reconfig_info->link_info[reconfig_info->num_links].link_id = linkid;
reconfig_info->link_info[reconfig_info->num_links].is_delete_timer_p = is_delete_timer_valid;
if (is_delete_timer_valid)
reconfig_info->link_info[reconfig_info->num_links].delete_timer = delete_timer;
if (is_ap_removal_timer_valid)
link_info->ap_removal_timer = ap_removal_timer;
else
mlo_warn_rl("Delete timer not found in STA Info field of per-STA profile with link ID %u",
linkid);
mlo_debug("Per-STA Profile Link ID: %u Delete timer present: %d Delete timer: %u",
reconfig_info->link_info[reconfig_info->num_links].link_id,
reconfig_info->link_info[reconfig_info->num_links].is_delete_timer_p,
reconfig_info->link_info[reconfig_info->num_links].delete_timer);
mlo_debug("Per-STA Profile Link ID: %u AP removal timer present: %d AP removal timer: %u",
link_info->link_id,
link_info->is_ap_removal_timer_p,
link_info->ap_removal_timer);
reconfig_info->num_links++;
}

Visa fil

@@ -2283,7 +2283,7 @@ static void mlo_process_link_remove(struct wlan_objmgr_vdev *vdev,
/* Link delete triggered from AP,
* start timer with tbtt count * beacon interval
*/
tbtt_count = link_info->delete_timer;
tbtt_count = link_info->ap_removal_timer;
bcn_int = mlo_get_bcn_interval_by_bssid(
wlan_vdev_get_pdev(vdev),
wlan_peer_get_macaddr(bss_peer));