diff --git a/umac/mlo_mgr/inc/utils_mlo.h b/umac/mlo_mgr/inc/utils_mlo.h index a4c6673de7..2190a0bb04 100644 --- a/umac/mlo_mgr/inc/utils_mlo.h +++ b/umac/mlo_mgr/inc/utils_mlo.h @@ -411,9 +411,12 @@ util_get_bvmlie_mldcap(uint8_t *mlieseq, qdf_size_t mlieseqlen, * profile is found, or if none of the per-STA profiles includes a MAC address * in the STA Info field (assuming no errors are encountered). * - * Get partner link information in the per-STA profiles present in a Basic - * variant Multi-Link element. The partner link information is returned only for - * those per-STA profiles which have a MAC address in the STA Info field. + * Get partner link information and NSTR capability information in the + * per-STA profiles present in a Basic variant Multi-Link element. + * The partner link information is returned only for those per-STA profiles + * which have a MAC address in the STA Info field. + * The NSTR capability information is returned only for those per-STA profiles + * which are Complete per-STA profiles. * * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving * the reason for error in the case of failure diff --git a/umac/mlo_mgr/inc/wlan_mlo_mgr_public_structs.h b/umac/mlo_mgr/inc/wlan_mlo_mgr_public_structs.h index 684267457a..0348b54694 100644 --- a/umac/mlo_mgr/inc/wlan_mlo_mgr_public_structs.h +++ b/umac/mlo_mgr/inc/wlan_mlo_mgr_public_structs.h @@ -618,6 +618,20 @@ struct wlan_mlo_mld_cap { reserved:3; }; +/** + * struct mlo_nstr_info - MLO NSTR capability info + * @link_id: Lind Id + * @nstr_lp_present: Flag for NSTR link pair presence + * @nstr_bmp_size: NSTR Bitmap Size + * @nstr_lp_bitmap: NSTR link pair bitmap of link_id + */ +struct mlo_nstr_info { + uint8_t link_id; + bool nstr_lp_present; + uint8_t nstr_bmp_size; + uint16_t nstr_lp_bitmap; +}; + /** * struct wlan_mlo_peer_context - MLO peer context * @@ -647,6 +661,7 @@ struct wlan_mlo_mld_cap { * @is_mesh_ml_peer: flag to indicate if ml_peer is MESH configured * @mesh_config: eack link peer's MESH configuration * @mlpeer_mldcap: MLD Capability information for ML peer + * @mlpeer_nstrinfo: NSTR Capability info */ struct wlan_mlo_peer_context { qdf_list_node_t peer_node; @@ -687,6 +702,7 @@ struct wlan_mlo_peer_context { struct mlnawds_config mesh_config[MAX_MLO_LINK_PEERS]; #endif struct wlan_mlo_mld_cap mlpeer_mldcap; + struct mlo_nstr_info mlpeer_nstrinfo[WLAN_UMAC_MLO_MAX_VDEVS]; }; /** @@ -718,12 +734,16 @@ struct mlo_link_info { * @num_partner_links: no. of partner links * @partner_link_info: per partner link info * @t2lm_enable_val: enum wlan_t2lm_enable + * @nstr_info: NSTR Capability info + * @num_nstr_info_links: No. of links for which NSTR info is present */ struct mlo_partner_info { uint8_t num_partner_links; struct mlo_link_info partner_link_info[WLAN_UMAC_MLO_MAX_VDEVS]; #ifdef WLAN_FEATURE_11BE enum wlan_t2lm_enable t2lm_enable_val; + struct mlo_nstr_info nstr_info[WLAN_UMAC_MLO_MAX_VDEVS]; + uint8_t num_nstr_info_links; #endif }; diff --git a/umac/mlo_mgr/src/utils_mlo.c b/umac/mlo_mgr/src/utils_mlo.c index 22bcd2c0d2..7f0a98cccc 100644 --- a/umac/mlo_mgr/src/utils_mlo.c +++ b/umac/mlo_mgr/src/utils_mlo.c @@ -370,13 +370,17 @@ util_parse_bvmlie_perstaprofile_stactrl(uint8_t *subelempayload, struct qdf_mac_addr *macaddr, bool is_staprof_reqd, uint8_t **staprof, - qdf_size_t *staprof_len) + qdf_size_t *staprof_len, + struct mlo_nstr_info *nstr_info, + bool *is_nstrlp_present) { qdf_size_t parsed_payload_len = 0; uint16_t stacontrol; uint8_t completeprofile; uint8_t nstrlppresent; enum wlan_ml_bv_linfo_perstaprof_stactrl_nstrbmsz nstrbmsz; + qdf_size_t nstrlpoffset = 0; + uint8_t link_id; /* This helper returns the location(s) and where required, the length(s) * of (sub)field(s) inferable after parsing the STA Control field in the @@ -416,11 +420,11 @@ util_parse_bvmlie_perstaprofile_stactrl(uint8_t *subelempayload, stacontrol = le16toh(stacontrol); parsed_payload_len += WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_SIZE; - if (linkid) { - *linkid = QDF_GET_BITS(stacontrol, - WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_LINKID_IDX, - WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_LINKID_BITS); - } + link_id = QDF_GET_BITS(stacontrol, + WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_LINKID_IDX, + WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_LINKID_BITS); + if (linkid) + *linkid = link_id; /* Check if this a complete profile */ completeprofile = QDF_GET_BITS(stacontrol, @@ -556,6 +560,7 @@ util_parse_bvmlie_perstaprofile_stactrl(uint8_t *subelempayload, WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_NSTRLINKPRP_BITS); if (completeprofile && nstrlppresent) { + nstrlpoffset = parsed_payload_len; /* Check NTSR Bitmap Size bit */ nstrbmsz = QDF_GET_BITS(stacontrol, @@ -590,6 +595,20 @@ util_parse_bvmlie_perstaprofile_stactrl(uint8_t *subelempayload, mlo_err_rl("Invalid NSTR Bitmap size %u", nstrbmsz); return QDF_STATUS_E_PROTO; } + if (nstr_info) { + nstr_info->nstr_lp_present = nstrlppresent; + nstr_info->nstr_bmp_size = nstrbmsz; + *is_nstrlp_present = true; + nstr_info->link_id = link_id; + + if (nstrbmsz == WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_NSTRBMSZ_1_OCTET) { + nstr_info->nstr_lp_bitmap = + *(uint8_t *)(subelempayload + nstrlpoffset); + } else if (nstrbmsz == WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_NSTRBMSZ_2_OCTETS) { + nstr_info->nstr_lp_bitmap = + qdf_le16_to_cpu(*(uint16_t *)(subelempayload + nstrlpoffset)); + } + } } /* Check BSS Parameters Change Count Present bit */ @@ -757,6 +776,7 @@ QDF_STATUS util_parse_partner_info_from_linkinfo(uint8_t *linkinfo, { uint8_t linkid; struct qdf_mac_addr macaddr; + struct mlo_nstr_info nstr_info = {0}; bool is_macaddr_valid; uint8_t *linkinfo_currpos; qdf_size_t linkinfo_remlen; @@ -766,6 +786,7 @@ QDF_STATUS util_parse_partner_info_from_linkinfo(uint8_t *linkinfo, qdf_size_t subelemseqpayloadlen; qdf_size_t defragpayload_len; QDF_STATUS ret; + bool is_nstrlp_present = false; /* This helper function parses partner info from the per-STA profiles * present (if any) in the Link Info field in the payload of a Multi @@ -883,11 +904,26 @@ QDF_STATUS util_parse_partner_info_from_linkinfo(uint8_t *linkinfo, &macaddr, false, NULL, - NULL); + NULL, + &nstr_info, + &is_nstrlp_present); if (QDF_IS_STATUS_ERROR(ret)) { return ret; } + if (is_nstrlp_present) { + if (partner_info->num_nstr_info_links >= + QDF_ARRAY_SIZE(partner_info->nstr_info)) { + mlo_err_rl("Insufficient size %zu of array for nstr link info", + QDF_ARRAY_SIZE(partner_info->nstr_info)); + return QDF_STATUS_E_NOMEM; + } + qdf_mem_copy(&partner_info->nstr_info[partner_info->num_nstr_info_links], + &nstr_info, sizeof(nstr_info)); + partner_info->num_nstr_info_links++; + is_nstrlp_present = false; + } + if (is_macaddr_valid) { if (partner_info->num_partner_links >= QDF_ARRAY_SIZE(partner_info->partner_link_info)) { @@ -1754,6 +1790,8 @@ util_find_bvmlie_persta_prof_for_linkid(uint8_t req_link_id, &macaddr, false, NULL, + NULL, + NULL, NULL); if (QDF_IS_STATUS_ERROR(ret)) return ret; @@ -2179,7 +2217,9 @@ QDF_STATUS util_gen_link_reqrsp_cmn(uint8_t *frame, qdf_size_t frame_len, &reportedmacaddr, true, &sta_prof_currpos, - &sta_prof_remlen); + &sta_prof_remlen, + NULL, + NULL); if (QDF_IS_STATUS_ERROR(ret)) { qdf_mem_free(mlieseqpayload_copy); return ret; diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index 3cbe5dca9c..90a66f63df 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -1217,6 +1217,9 @@ struct wmi_host_link_state_params { * @emlsr_support: indicate if eMLSR supported * @emlmr_support: indicate if eMLMR supported * @msd_cap_support: indicate if MSD supported + * @nstr_bitmap_present: indicate if NSTR bitmap is present + * @nstr_bitmap_size: Indicates size of NSTR bitmap, + * as per the 802.11be specification * @unused: spare bits * @mld_mac: MLD mac address * @logical_link_index: Unique index for links of the mlo. Starts with Zero @@ -1231,6 +1234,7 @@ struct wmi_host_link_state_params { * @medium_sync_max_txop_num: Max number of TXOPs * @max_num_simultaneous_links: Max number of simultaneous links as per * MLD Capability for ML peer + * @nstr_indication_bitmap: NSTR indication bitmap */ struct peer_assoc_mlo_params { uint32_t mlo_enabled:1, @@ -1242,7 +1246,9 @@ struct peer_assoc_mlo_params { emlsr_support:1, emlmr_support:1, msd_cap_support:1, - unused:23; + nstr_bitmap_present:1, + nstr_bitmap_size:1, + unused:21; uint8_t mld_mac[QDF_MAC_ADDR_SIZE]; uint32_t logical_link_index; uint32_t ml_peer_id; @@ -1255,6 +1261,7 @@ struct peer_assoc_mlo_params { uint16_t medium_sync_ofdm_ed_thresh; uint16_t medium_sync_max_txop_num; uint16_t max_num_simultaneous_links; + uint32_t nstr_indication_bitmap; }; /** diff --git a/wmi/src/wmi_unified_11be_tlv.c b/wmi/src/wmi_unified_11be_tlv.c index 9084c00410..a7ad30a436 100644 --- a/wmi/src/wmi_unified_11be_tlv.c +++ b/wmi/src/wmi_unified_11be_tlv.c @@ -298,6 +298,12 @@ uint8_t *peer_assoc_add_mlo_params(uint8_t *buf_ptr, mlo_params->max_num_simultaneous_links = req->mlo_params.max_num_simultaneous_links; + mlo_params->mlo_flags.nstr_bitmap_present = + req->mlo_params.nstr_bitmap_present; + mlo_params->mlo_flags.nstr_bitmap_size = + req->mlo_params.nstr_bitmap_size; + mlo_params->nstr_indication_bitmap = + req->mlo_params.nstr_indication_bitmap; return buf_ptr + sizeof(wmi_peer_assoc_mlo_params); }