diff --git a/wmi/inc/wmi_unified_11be_tlv.h b/wmi/inc/wmi_unified_11be_tlv.h index 80c5aadb0e..ebc6490aa4 100644 --- a/wmi/inc/wmi_unified_11be_tlv.h +++ b/wmi/inc/wmi_unified_11be_tlv.h @@ -74,6 +74,31 @@ uint8_t *peer_create_add_mlo_params(uint8_t *buf_ptr, * Return: size of ML params in peer create cmd */ size_t peer_create_mlo_params_size(struct peer_create_params *req); +/** + * peer_assoc_mlo_params_size() - Get ML params size in peer assoc + * @req: pointer to peer assoc request param + * + * Return: size of ML params in peer assoc cmd + */ +size_t peer_assoc_mlo_params_size(struct peer_assoc_params *req); +/** + * peer_assoc_add_mlo_params() - Add MLO params in peer assoc cmd + * @buf_ptr: pointer to peer assoc cmd buffer. + * @req: pointer to peer assoc request param + * + * Return: pointer to new offset of cmd buffer + */ +uint8_t *peer_assoc_add_mlo_params(uint8_t *buf_ptr, + struct peer_assoc_params *req); +/** + * peer_assoc_add_ml_partner_links() - Add MLO partner links in peer assoc cmd + * @buf_ptr: pointer to peer assoc cmd buffer. + * @req: pointer to peer assoc request param + * + * Return: pointer to new offset of cmd buffer + */ +uint8_t *peer_assoc_add_ml_partner_links(uint8_t *buf_ptr, + struct peer_assoc_params *req); #else static uint8_t *vdev_create_add_mlo_params(uint8_t *buf_ptr, struct vdev_create_params *param) @@ -117,5 +142,29 @@ static size_t peer_create_mlo_params_size(struct peer_create_params *req) { return WMI_TLV_HDR_SIZE; } + +static size_t peer_assoc_mlo_params_size(struct peer_assoc_params *req) +{ + size_t peer_assoc_mlo_size = + WMI_TLV_HDR_SIZE + + WMI_TLV_HDR_SIZE; + + return peer_assoc_mlo_size; +} + +static uint8_t *peer_assoc_add_mlo_params(uint8_t *buf_ptr, + struct peer_assoc_params *req) +{ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); + return buf_ptr + WMI_TLV_HDR_SIZE; +} + +static uint8_t *peer_assoc_add_ml_partner_links(uint8_t *buf_ptr, + struct peer_assoc_params *req) +{ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); + return buf_ptr + WMI_TLV_HDR_SIZE; +} + #endif /*WLAN_FEATURE_11BE_MLO*/ #endif /*_WMI_UNIFIED_11BE_TLV_H_*/ diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index e476715905..e5dcfa9e90 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -1019,6 +1019,52 @@ typedef struct { uint32_t mac_addr47to32; } wmi_host_mac_addr; +#ifdef WLAN_FEATURE_11BE_MLO +/** + * struct peer_assoc_mlo_params - MLO assoc params + * @mlo_enabled: indicate is MLO enabled + * @mlo_assoc_link: indicate is the link used to initialize the association + * of mlo connection + * @mlo_primary_umac: indicate is the link on primary UMAC, WIN only flag + * @mlo_logical_link_index_valid: indicate if the logial link index in is valid + * @mlo_peer_id_valid: indicate if the mlo peer id is valid + * @mld_mac: MLD mac address + * @logical_link_index: Unique index for links of the mlo. Starts with Zero + * @ml_peer_id: ML peer id if generated by host. Otherwise invalid peer id + */ +struct peer_assoc_mlo_params { + uint32_t mlo_enabled:1, + mlo_assoc_link:1, + mlo_primary_umac:1, + mlo_logical_link_index_valid:1, + mlo_peer_id_valid:1, + unused:27; + uint8_t mld_mac[QDF_MAC_ADDR_SIZE]; + uint32_t logical_link_index; + uint32_t ml_peer_id; +}; + +/** + * struct ml_partner_info - partner link info + * @vdev_id: vdev id + * @hw_mld_link_id: unique hw link id across SoCs + */ +struct ml_partner_info { + uint32_t vdev_id; + uint32_t hw_mld_link_id; +}; + +#define WMI_MAX_ML_PARTNER_LINKS 4 +/** + * struct peer_assoc_ml_partner_links - ML partner links + * @num_links: Number of links + * @partner_info: Partner link info + */ +struct peer_assoc_ml_partner_links { + uint8_t num_links; + struct ml_partner_info partner_info[WMI_MAX_ML_PARTNER_LINKS]; +}; +#endif /** * struct peer_assoc_params - peer assoc cmd parameter * @vdev_id: vdev id @@ -1086,6 +1132,8 @@ typedef struct { * @peer_ppet: Peer HE PPET info * @peer_bss_max_idle_option: Peer BSS Max Idle option update * @akm: AKM info + * @peer_assoc_mlo_params mlo_params: MLO assoc params + * @peer_assoc_ml_partner_links: MLO patner links */ struct peer_assoc_params { uint32_t vdev_id; @@ -1164,6 +1212,10 @@ struct peer_assoc_params { u_int8_t peer_bsscolor_rept_info; uint32_t peer_bss_max_idle_option; uint16_t akm; +#ifdef WLAN_FEATURE_11BE_MLO + struct peer_assoc_mlo_params mlo_params; + struct peer_assoc_ml_partner_links ml_links; +#endif }; /** diff --git a/wmi/src/wmi_unified_11be_tlv.c b/wmi/src/wmi_unified_11be_tlv.c index f0e0cd858b..12a481b072 100644 --- a/wmi/src/wmi_unified_11be_tlv.c +++ b/wmi/src/wmi_unified_11be_tlv.c @@ -138,3 +138,77 @@ uint8_t *peer_create_add_mlo_params(uint8_t *buf_ptr, return buf_ptr + sizeof(wmi_peer_create_mlo_params); } + +size_t peer_assoc_mlo_params_size(struct peer_assoc_params *req) +{ + size_t peer_assoc_mlo_size = sizeof(wmi_peer_assoc_mlo_params) + + WMI_TLV_HDR_SIZE + + (req->ml_links.num_links * + sizeof(wmi_peer_assoc_mlo_partner_link_params)) + + WMI_TLV_HDR_SIZE; + + return peer_assoc_mlo_size; +} + +uint8_t *peer_assoc_add_mlo_params(uint8_t *buf_ptr, + struct peer_assoc_params *req) +{ + wmi_peer_assoc_mlo_params *mlo_params; + + /* Add WMI peer assoc mlo params */ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + sizeof(wmi_peer_assoc_mlo_params)); + buf_ptr += sizeof(uint32_t); + + mlo_params = (wmi_peer_assoc_mlo_params *)buf_ptr; + WMITLV_SET_HDR(&mlo_params->tlv_header, + WMITLV_TAG_STRUC_wmi_peer_assoc_mlo_params, + WMITLV_GET_STRUCT_TLVLEN(wmi_peer_assoc_mlo_params)); + + mlo_params->mlo_flags.mlo_flags = 0; + WMI_MLO_FLAGS_SET_ENABLED(mlo_params->mlo_flags.mlo_flags, + req->mlo_params.mlo_enabled); + WMI_MLO_FLAGS_SET_ASSOC_LINK(mlo_params->mlo_flags.mlo_flags, + req->mlo_params.mlo_assoc_link); + WMI_MLO_FLAGS_SET_PRIMARY_UMAC(mlo_params->mlo_flags.mlo_flags, + req->mlo_params.mlo_primary_umac); + WMI_MLO_FLAGS_SET_LINK_INDEX_VALID(mlo_params->mlo_flags.mlo_flags, + req->mlo_params.mlo_logical_link_index_valid); + WMI_MLO_FLAGS_SET_PEER_ID_VALID(mlo_params->mlo_flags.mlo_flags, + req->mlo_params.mlo_peer_id_valid); + + WMI_CHAR_ARRAY_TO_MAC_ADDR(req->mlo_params.mld_mac, + &mlo_params->mld_macaddr); + mlo_params->logical_link_index = req->mlo_params.logical_link_index; + mlo_params->mld_peer_id = req->mlo_params.ml_peer_id; + + return buf_ptr + sizeof(wmi_peer_assoc_mlo_params); +} + +uint8_t *peer_assoc_add_ml_partner_links(uint8_t *buf_ptr, + struct peer_assoc_params *req) +{ + wmi_peer_assoc_mlo_partner_link_params *ml_partner_link; + struct ml_partner_info *partner_info; + uint8_t i; + + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + (req->ml_links.num_links * + sizeof(wmi_peer_assoc_mlo_partner_link_params))); + buf_ptr += sizeof(uint32_t); + + ml_partner_link = (wmi_peer_assoc_mlo_partner_link_params *)buf_ptr; + partner_info = req->ml_links.partner_info; + for (i = 0; i < req->ml_links.num_links; i++) { + WMITLV_SET_HDR(&ml_partner_link->tlv_header, + WMITLV_TAG_STRUC_wmi_peer_assoc_mlo_partner_link_params, + WMITLV_GET_STRUCT_TLVLEN(wmi_peer_assoc_mlo_partner_link_params)); + ml_partner_link->vdev_id = partner_info[i].vdev_id; + ml_partner_link->hw_mld_link_id = partner_info[i].hw_mld_link_id; + ml_partner_link++; + } + + return buf_ptr + + (req->ml_links.num_links * + sizeof(wmi_peer_assoc_mlo_partner_link_params)); +} diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index e93d70b2c0..c6d67e7c7a 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -2631,7 +2631,7 @@ static inline void copy_peer_mac_addr_tlv( } #ifdef WLAN_FEATURE_11BE -static inline void update_peer_flags_tlv_ehtinfo( +static uint8_t *update_peer_flags_tlv_ehtinfo( wmi_peer_assoc_complete_cmd_fixed_param * cmd, struct peer_assoc_params *param, uint8_t *buf_ptr) { @@ -2681,12 +2681,15 @@ static inline void update_peer_flags_tlv_ehtinfo( cmd->peer_eht_cap_mac[1], cmd->peer_eht_ops, cmd->peer_eht_cap_phy[0], cmd->peer_he_cap_phy[1], cmd->peer_eht_cap_phy[2]); + + return buf_ptr; } #else -static inline void update_peer_flags_tlv_ehtinfo( +static uint8_t *update_peer_flags_tlv_ehtinfo( wmi_peer_assoc_complete_cmd_fixed_param * cmd, struct peer_assoc_params *param, uint8_t *buf_ptr) { + return buf_ptr; } #endif @@ -2694,8 +2697,7 @@ static inline void update_peer_flags_tlv_ehtinfo( static uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) { - return (sizeof(wmi_peer_assoc_mlo_params) + WMI_TLV_HDR_SIZE) + - (sizeof(wmi_he_rate_set) * param->peer_eht_mcs_count + return (sizeof(wmi_he_rate_set) * param->peer_eht_mcs_count + WMI_TLV_HDR_SIZE); } @@ -2704,15 +2706,6 @@ static void wmi_populate_service_11be(uint32_t *wmi_service) wmi_service[wmi_service_11be] = WMI_SERVICE_11BE; } -static uint32_t wmi_update_peer_assoc_mlo_params(uint8_t *buf_ptr) -{ - WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, - sizeof(wmi_peer_assoc_mlo_params)); - WMITLV_SET_HDR(buf_ptr + WMI_TLV_HDR_SIZE, - WMITLV_TAG_STRUC_wmi_peer_assoc_mlo_params, - WMITLV_GET_STRUCT_TLVLEN(wmi_peer_assoc_mlo_params)); - return WMI_TLV_HDR_SIZE + sizeof(wmi_peer_assoc_mlo_params); -} #else static uint32_t wmi_eht_peer_assoc_params_len(struct peer_assoc_params *param) @@ -2724,10 +2717,6 @@ static void wmi_populate_service_11be(uint32_t *wmi_service) { } -static uint32_t wmi_update_peer_assoc_mlo_params(uint8_t *buf_ptr) -{ - return 0; -} #endif /** @@ -2762,7 +2751,8 @@ static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle, sizeof(wmi_vht_rate_set) + (sizeof(wmi_he_rate_set) * param->peer_he_mcs_count + WMI_TLV_HDR_SIZE) - + wmi_eht_peer_assoc_params_len(param); + + wmi_eht_peer_assoc_params_len(param) + + peer_assoc_mlo_params_size(param); buf = wmi_buf_alloc(wmi_handle, len); if (!buf) @@ -2899,9 +2889,11 @@ static QDF_STATUS send_peer_assoc_cmd_tlv(wmi_unified_t wmi_handle, cmd->peer_he_cap_phy[2], cmd->peer_bw_rxnss_override); - buf_ptr += wmi_update_peer_assoc_mlo_params(buf_ptr); + buf_ptr = peer_assoc_add_mlo_params(buf_ptr, param); - update_peer_flags_tlv_ehtinfo(cmd, param, buf_ptr); + buf_ptr = update_peer_flags_tlv_ehtinfo(cmd, param, buf_ptr); + + buf_ptr = peer_assoc_add_ml_partner_links(buf_ptr, param); wmi_mtrace(WMI_PEER_ASSOC_CMDID, cmd->vdev_id, 0); ret = wmi_unified_cmd_send(wmi_handle, buf, len,