diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h index eaf711a336..01c182296a 100644 --- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h +++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h @@ -1599,7 +1599,7 @@ bool wlan_vdev_mlme_is_mlo_mcast_vdev(struct wlan_objmgr_vdev *vdev) #endif /** - * wlan_vdev_mlme_is_mlo_vdev() - whether it is mlo sta link vdev or not + * wlan_vdev_mlme_is_mlo_link_vdev() - whether it is mlo sta link vdev or not * @vdev: VDEV object * * Return: True if it is mlo sta link, otherwise false. diff --git a/umac/mlo_mgr/inc/wlan_mlo_mgr_cmn.h b/umac/mlo_mgr/inc/wlan_mlo_mgr_cmn.h index 9f22fd8918..77a84c9b09 100644 --- a/umac/mlo_mgr/inc/wlan_mlo_mgr_cmn.h +++ b/umac/mlo_mgr/inc/wlan_mlo_mgr_cmn.h @@ -409,9 +409,8 @@ QDF_STATUS mlo_ser_set_link_req(struct mlo_link_set_active_req *req); typedef void (*mlo_vdev_ops_handler)(struct wlan_objmgr_vdev *vdev, void *arg); -/* - * mlo_iterate_ml_vdev_list: Iterate on ML vdevs of MLD - * +/** + * mlo_iterate_ml_vdev_list() - Iterate on ML vdevs of MLD * @vdev: vdev object * @handler: the handler will be called for each object in ML list * @arg: argument to be passed to handler @@ -458,5 +457,27 @@ void mlo_iterate_ml_vdev_list(struct wlan_objmgr_vdev *vdev, mlo_dev_lock_release(mlo_dev_ctx); } +/** + * struct mlo_stats_vdev_params - vdev params for MLO stats request + * @ml_vdev_count: Num of connected mlo vdevs + * @ml_vdev_id: vdev_ids of ml vdevs + */ +struct mlo_stats_vdev_params { + uint8_t ml_vdev_count; + uint8_t ml_vdev_id[WLAN_UMAC_MLO_MAX_VDEVS]; +}; + +/** + * mlo_get_mlstats_vdev_params() - Get vdev params for MLO stats + * @psoc: psoc object + * @vdev_id: vdev id + * @ml_vdev_info: pointer to mlo_stats_vdev_params + * + * Return: QDF_STATUS + */ +QDF_STATUS +mlo_get_mlstats_vdev_params(struct wlan_objmgr_psoc *psoc, + struct mlo_stats_vdev_params *ml_vdev_info, + uint8_t vdev_id); #endif #endif diff --git a/umac/mlo_mgr/src/wlan_mlo_mgr_cmn.c b/umac/mlo_mgr/src/wlan_mlo_mgr_cmn.c index 204c03fcbc..8a1bea477c 100644 --- a/umac/mlo_mgr/src/wlan_mlo_mgr_cmn.c +++ b/umac/mlo_mgr/src/wlan_mlo_mgr_cmn.c @@ -625,3 +625,31 @@ void mlo_mlme_handle_sta_csa_param(struct wlan_objmgr_vdev *vdev, mlo_ctx->mlme_ops->mlo_mlme_ext_handle_sta_csa_param(vdev, csa_param); } + +QDF_STATUS +mlo_get_mlstats_vdev_params(struct wlan_objmgr_psoc *psoc, + struct mlo_stats_vdev_params *info, + uint8_t vdev_id) +{ + struct wlan_objmgr_vdev *ml_vdev_list[WLAN_UMAC_MLO_MAX_VDEVS] = {0}; + struct wlan_objmgr_vdev *vdev; + int i; + uint16_t ml_vdev_cnt = 0; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_MLO_MGR_ID); + if (!vdev) { + mlo_err("vdev object is NULL for vdev %d", vdev_id); + return QDF_STATUS_E_INVAL; + } + + mlo_get_ml_vdev_list(vdev, &ml_vdev_cnt, ml_vdev_list); + for (i = 0; i < ml_vdev_cnt; i++) { + info->ml_vdev_id[i] = wlan_vdev_get_id(ml_vdev_list[i]); + mlo_release_vdev_ref(ml_vdev_list[i]); + } + info->ml_vdev_count = ml_vdev_cnt; + mlo_release_vdev_ref(vdev); + + return QDF_STATUS_SUCCESS; +} diff --git a/umac/mlo_mgr/src/wlan_mlo_mgr_sta.c b/umac/mlo_mgr/src/wlan_mlo_mgr_sta.c index 2607814c0a..89a06807ba 100644 --- a/umac/mlo_mgr/src/wlan_mlo_mgr_sta.c +++ b/umac/mlo_mgr/src/wlan_mlo_mgr_sta.c @@ -579,7 +579,7 @@ mlo_send_link_connect(struct wlan_objmgr_vdev *vdev, &ssid.length); if (!ml_parnter_info->num_partner_links) { - mlo_err("No patner info in connect resp"); + mlo_err("No partner info in connect resp"); return; } @@ -619,7 +619,7 @@ mlo_send_link_connect(struct wlan_objmgr_vdev *vdev, uint8_t j = 0; if (!ml_parnter_info->num_partner_links) { - mlo_err("No patner info in connect resp"); + mlo_err("No partner info in connect resp"); return; } diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index a8e974f9df..87af46bef0 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -1222,7 +1222,7 @@ struct peer_assoc_ml_partner_links { * @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 + * @peer_assoc_ml_partner_links: MLO partner links * @t2lm_params: TID-to-link mapping params */ struct peer_assoc_params { @@ -2338,12 +2338,20 @@ struct ll_stats_set_params { * @vdev_id: vdev id * @param_id_mask: param is mask * @peer_macaddr: MAC address of the peer for which stats are desired + * @is_mlo_req: is the request for mlo vdev + * @vdev_id_bitmap: vdev_id_bitmap of all the connected mlo vdevs + * @mld_macaddr: MLD MAC address */ struct ll_stats_get_params { uint32_t req_id; uint8_t vdev_id; uint32_t param_id_mask; struct qdf_mac_addr peer_macaddr; +#ifdef WLAN_FEATURE_11BE_MLO + bool is_mlo_req; + uint32_t vdev_id_bitmap; + struct qdf_mac_addr mld_macaddr; +#endif }; diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index d277d2ab25..a535892233 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -5812,6 +5812,77 @@ static QDF_STATUS send_process_ll_stats_get_cmd_tlv(wmi_unified_t wmi_handle, return QDF_STATUS_SUCCESS; } +#ifdef WLAN_FEATURE_11BE_MLO +static int +wmi_get_tlv_length_for_mlo_stats(const struct ll_stats_get_params *get_req) +{ + int32_t len = 0; + + /* In case of MLO connection, update the length of the buffer. + * The wmi_inst_rssi_stats_params structure is not needed for MLO stats, + * hence just update the TLV header, but allocate no memory for it. + */ + if (!get_req->is_mlo_req) + return len; + + len += WMI_TLV_HDR_SIZE + 0 * sizeof(wmi_inst_rssi_stats_params) + + WMI_TLV_HDR_SIZE + 1 * sizeof(uint32_t) + + WMI_TLV_HDR_SIZE + 1 * sizeof(wmi_mac_addr); + + return len; +} + +static void +wmi_update_tlv_headers_for_mlo_stats(const struct ll_stats_get_params *get_req, + void *buf_ptr) +{ + wmi_request_unified_ll_get_sta_cmd_fixed_param *unified_cmd; + uint32_t *vdev_id_bitmap; + wmi_mac_addr *mld_mac; + + /* In case of MLO connection, update the TLV Headers */ + if (!get_req->is_mlo_req) + return; + + buf_ptr += sizeof(*unified_cmd); + + /* Fill TLV but no data for wmi_inst_rssi_stats_params */ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0); + buf_ptr += WMI_TLV_HDR_SIZE; + + /* Adding vdev_bitmap_id array TLV */ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, + sizeof(*vdev_id_bitmap)); + buf_ptr += WMI_TLV_HDR_SIZE; + vdev_id_bitmap = buf_ptr; + *(vdev_id_bitmap) = get_req->vdev_id_bitmap; + buf_ptr += sizeof(*vdev_id_bitmap); + + /* Adding mld_macaddr array TLV */ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, + sizeof(*mld_mac)); + buf_ptr += WMI_TLV_HDR_SIZE; + mld_mac = buf_ptr; + WMI_CHAR_ARRAY_TO_MAC_ADDR(get_req->mld_macaddr.bytes, mld_mac); + + wmi_debug("MLO vdev_id_bitmap: 0x%x MLD MAC Addr: " + QDF_MAC_ADDR_FMT, get_req->vdev_id_bitmap, + QDF_MAC_ADDR_REF(get_req->mld_macaddr.bytes)); +} +#else +static inline int +wmi_get_tlv_length_for_mlo_stats(const struct ll_stats_get_params *get_req) +{ + return 0; +} + +static inline void +wmi_update_tlv_headers_for_mlo_stats(const struct ll_stats_get_params *get_req, + void *buf_ptr) +{ +} +#endif + #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION /** * send_unified_ll_stats_get_sta_cmd_tlv() - unified link layer stats and get @@ -5833,8 +5904,9 @@ static QDF_STATUS send_unified_ll_stats_get_sta_cmd_tlv( bool is_ll_get_sta_stats_over_qmi; len = sizeof(*unified_cmd); - buf = wmi_buf_alloc(wmi_handle, len); + len += wmi_get_tlv_length_for_mlo_stats(get_req); + buf = wmi_buf_alloc(wmi_handle, len); if (!buf) return QDF_STATUS_E_NOMEM; @@ -5868,6 +5940,7 @@ static QDF_STATUS send_unified_ll_stats_get_sta_cmd_tlv( get_req->req_id, get_req->param_id_mask, get_req->vdev_id, QDF_MAC_ADDR_REF(get_req->peer_macaddr.bytes)); + wmi_update_tlv_headers_for_mlo_stats(get_req, buf_ptr); wmi_mtrace(WMI_REQUEST_UNIFIED_LL_GET_STA_CMDID, get_req->vdev_id, 0); /**