From 90dd00b3c6c9fa1307922cc77ae875c2783253b8 Mon Sep 17 00:00:00 2001 From: Deeksha Gupta Date: Thu, 17 Jun 2021 21:15:05 +0530 Subject: [PATCH] qcacld-3.0: Print all peer info for SAP TWT get_status Currently, host prints only one peer info instead of all peer info as part of oem_ss initiated broadcast SAP TWT get_status command. Add a support to print all peer info if oem_ss sends broadcast SAP TWT get_status command. Change-Id: I0a617f655b7a5486582cb47a4602b30514ffae88 CRs-Fixed: 2970487 --- .../inc/wlan_cp_stats_mc_ucfg_api.h | 4 +- .../src/wlan_cp_stats_mc_ucfg_api.c | 185 ++++++++++-------- core/hdd/src/wlan_hdd_twt.c | 66 +++++-- 3 files changed, 149 insertions(+), 106 deletions(-) diff --git a/components/cp_stats/dispatcher/inc/wlan_cp_stats_mc_ucfg_api.h b/components/cp_stats/dispatcher/inc/wlan_cp_stats_mc_ucfg_api.h index 7ff3110f853d..a41fc7cf5d1a 100644 --- a/components/cp_stats/dispatcher/inc/wlan_cp_stats_mc_ucfg_api.h +++ b/components/cp_stats/dispatcher/inc/wlan_cp_stats_mc_ucfg_api.h @@ -55,9 +55,9 @@ * @params: array pointer to store peer twt session parameters, should contain * mac_addr and dialog id of a peer for which twt session stats to be retrieved * - * Return: QDF_STATUS_SUCCESS upon success, else qdf error values + * Return: total number of valid twt session */ -QDF_STATUS +int ucfg_twt_get_peer_session_params(struct wlan_objmgr_psoc *psoc_obj, struct wmi_host_twt_session_stats_info *param); #endif /* WLAN_SUPPORT_TWT */ diff --git a/components/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c b/components/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c index b2b09c651c32..2fbbc8bdf271 100644 --- a/components/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c +++ b/components/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c @@ -35,6 +35,7 @@ #ifdef WLAN_SUPPORT_TWT #include #endif +#include #ifdef WLAN_SUPPORT_TWT @@ -46,6 +47,7 @@ * @input_dialog_id: input dialog id * @dest_param: Pointer to copy twt session parameters when a peer with * given dialog id is found + * @num_twt_session: Pointer holding total number of valid twt session * * Return: Success if stats are copied for a peer with given dialog, * else failure @@ -54,11 +56,11 @@ static QDF_STATUS ucfg_twt_get_peer_session_param_by_dlg_id(struct peer_mc_cp_stats *mc_stats, uint32_t input_dialog_id, struct wmi_host_twt_session_stats_info - *dest_param) + *dest_param, int *num_twt_session) { struct wmi_host_twt_session_stats_info *src_param; uint32_t event_type; - int i, num_session = 0; + int i = 0; QDF_STATUS qdf_status = QDF_STATUS_E_INVAL; if (!mc_stats || !dest_param) @@ -75,11 +77,11 @@ ucfg_twt_get_peer_session_param_by_dlg_id(struct peer_mc_cp_stats *mc_stats, if ((event_type == HOST_TWT_SESSION_SETUP) || (event_type == HOST_TWT_SESSION_UPDATE)) { - qdf_mem_copy(&dest_param[num_session], src_param, + qdf_mem_copy(&dest_param[*num_twt_session], src_param, sizeof(*src_param)); qdf_status = QDF_STATUS_SUCCESS; - num_session += 1; - if (num_session >= TWT_PEER_MAX_SESSIONS) + *num_twt_session += 1; + if (*num_twt_session >= TWT_PEER_MAX_SESSIONS) break; } } @@ -95,9 +97,9 @@ ucfg_twt_get_peer_session_param_by_dlg_id(struct peer_mc_cp_stats *mc_stats, * @dialog_id: dialog id of peer for which twt session params to be retrieved * @params: pointer to store peer twt session parameters * - * Return: Retuns QDF_STATUS_SUCCESS upon success, else qdf error values + * Return: total number of valid twt session */ -static QDF_STATUS +static int ucfg_twt_get_single_peer_session_params(struct wlan_objmgr_psoc *psoc_obj, uint8_t *mac_addr, uint32_t dialog_id, struct wmi_host_twt_session_stats_info @@ -107,27 +109,30 @@ ucfg_twt_get_single_peer_session_params(struct wlan_objmgr_psoc *psoc_obj, struct peer_cp_stats *peer_cp_stats_priv; struct peer_mc_cp_stats *peer_mc_stats; QDF_STATUS qdf_status = QDF_STATUS_E_INVAL; + int num_twt_session = 0; if (!psoc_obj || !params) - return qdf_status; + return num_twt_session; peer = wlan_objmgr_get_peer_by_mac(psoc_obj, mac_addr, WLAN_CP_STATS_ID); if (!peer) - return qdf_status; + return num_twt_session; peer_cp_stats_priv = wlan_cp_stats_get_peer_stats_obj(peer); if (!peer_cp_stats_priv) { wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID); - return qdf_status; + return num_twt_session; } wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv); peer_mc_stats = peer_cp_stats_priv->peer_stats; - qdf_status = ucfg_twt_get_peer_session_param_by_dlg_id(peer_mc_stats, - dialog_id, - params); + qdf_status = ucfg_twt_get_peer_session_param_by_dlg_id( + peer_mc_stats, + dialog_id, + params, + &num_twt_session); if (QDF_IS_STATUS_ERROR(qdf_status)) { qdf_err("No TWT session for " QDF_MAC_ADDR_FMT " dialog_id %d", QDF_MAC_ADDR_REF(mac_addr), dialog_id); @@ -136,7 +141,7 @@ ucfg_twt_get_single_peer_session_params(struct wlan_objmgr_psoc *psoc_obj, wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv); wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID); - return qdf_status; + return num_twt_session; } /** @@ -144,7 +149,7 @@ ucfg_twt_get_single_peer_session_params(struct wlan_objmgr_psoc *psoc_obj, * a peer if twt session is valid * @mc_cp_stats: pointer to peer specific stats * @param: Pointer to copy twt session parameters - * @num_twt_sessions: Pointer holding total number of valid twt sessions + * @num_twt_sessions Pointer holding total number of valid twt sessions * * Return: QDF_STATUS success if valid twt session parameters are obtained * else other qdf error values @@ -152,7 +157,7 @@ ucfg_twt_get_single_peer_session_params(struct wlan_objmgr_psoc *psoc_obj, static QDF_STATUS ucfg_twt_get_peer_session_param(struct peer_mc_cp_stats *mc_cp_stats, struct wmi_host_twt_session_stats_info *params, - int *num_twt_sessions) + int *num_twt_session) { struct wmi_host_twt_session_stats_info *twt_params; QDF_STATUS qdf_status = QDF_STATUS_E_INVAL; @@ -169,12 +174,10 @@ ucfg_twt_get_peer_session_param(struct peer_mc_cp_stats *mc_cp_stats, /* Check twt session is established */ if ((event_type == HOST_TWT_SESSION_SETUP) || (event_type == HOST_TWT_SESSION_UPDATE)) { - qdf_mem_copy(¶ms[*num_twt_sessions], twt_params, + qdf_mem_copy(¶ms[*num_twt_session], twt_params, sizeof(*twt_params)); qdf_status = QDF_STATUS_SUCCESS; - *num_twt_sessions += 1; - if (*num_twt_sessions >= TWT_PSOC_MAX_SESSIONS) - break; + *num_twt_session += 1; } } return qdf_status; @@ -184,96 +187,108 @@ ucfg_twt_get_peer_session_param(struct peer_mc_cp_stats *mc_cp_stats, * ucfg_twt_get_all_peer_session_params()- Retrieves twt session parameters * of all peers with valid twt session * @psoc_obj: psoc object + * @vdvev_id: vdev_id * @params: array of pointer to store peer twt session parameters * - * Return: Retuns QDF_STATUS_SUCCESS upon success, else qdf error values + * Return: total number of valid twt sessions */ -static QDF_STATUS +static int ucfg_twt_get_all_peer_session_params(struct wlan_objmgr_psoc *psoc_obj, + uint8_t vdev_id, struct wmi_host_twt_session_stats_info *params) { - struct wlan_objmgr_psoc_objmgr *psoc_objmgr; - struct wlan_objmgr_peer *peer_obj; - struct wlan_peer_list *peer_list; - struct peer_cp_stats *cp_stats_peer_obj; + qdf_list_t *peer_list; + struct wlan_objmgr_peer *peer, *peer_next; + struct wlan_objmgr_vdev *vdev; + struct peer_cp_stats *cp_stats_peer_obj, *peer_cp_stat_prv; struct peer_mc_cp_stats *mc_cp_stats; - struct peer_cp_stats *peer_cp_stat_prv; - QDF_STATUS qdf_status = QDF_STATUS_E_INVAL; - qdf_list_t *obj_list; - int i, num_sessions = 0; + int num_twt_session = 0; + enum QDF_OPMODE opmode; + int sap_max_peer; - if (!psoc_obj || !params) - return qdf_status; - - /* psoc obj lock should be taken before peer list lock */ - wlan_psoc_obj_lock(psoc_obj); - psoc_objmgr = &psoc_obj->soc_objmgr; - /* List is empty, return */ - if (!psoc_objmgr->wlan_peer_count) { - wlan_psoc_obj_unlock(psoc_obj); - return qdf_status; + if (!psoc_obj) { + cp_stats_err("psoc is NULL"); + return num_twt_session; } - peer_list = &psoc_objmgr->peer_list; - qdf_spin_lock_bh(&peer_list->peer_list_lock); + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc_obj, vdev_id, + WLAN_CP_STATS_ID); - /* Iterate through peer_list to find a peer with valid twt sessions */ - for (i = 0; i < WLAN_PEER_HASHSIZE; i++) { - obj_list = &peer_list->peer_hash[i]; - peer_obj = wlan_psoc_peer_list_peek_head(obj_list); - while (peer_obj) { - cp_stats_peer_obj = - wlan_objmgr_peer_get_comp_private_obj - (peer_obj, WLAN_UMAC_COMP_CP_STATS); + if (!vdev) { + cp_stats_err("vdev is NULL, vdev_id: %d", vdev_id); + return num_twt_session; + } - mc_cp_stats = NULL; - if (cp_stats_peer_obj) - mc_cp_stats = cp_stats_peer_obj->peer_stats; + wlan_mlme_get_sap_max_peers(psoc_obj, &sap_max_peer); + opmode = wlan_vdev_mlme_get_opmode(vdev); - peer_cp_stat_prv = - wlan_cp_stats_get_peer_stats_obj(peer_obj); + peer_list = &vdev->vdev_objmgr.wlan_peer_list; + if (!peer_list) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID); + cp_stats_err("Peer list for vdev obj is NULL"); + return num_twt_session; + } - if (peer_cp_stat_prv && mc_cp_stats) { - wlan_cp_stats_peer_obj_lock(peer_cp_stat_prv); - ucfg_twt_get_peer_session_param(mc_cp_stats, - params, - &num_sessions); - wlan_cp_stats_peer_obj_unlock(peer_cp_stat_prv); - } + peer = wlan_vdev_peer_list_peek_active_head(vdev, peer_list, + WLAN_CP_STATS_ID); - if (num_sessions >= TWT_PSOC_MAX_SESSIONS) - goto done; - /* Get next peer */ - peer_obj = wlan_peer_get_next_peer_of_psoc(obj_list, - peer_obj); + while (peer) { + cp_stats_peer_obj = wlan_objmgr_peer_get_comp_private_obj( + peer, WLAN_UMAC_COMP_CP_STATS); + + mc_cp_stats = NULL; + if (cp_stats_peer_obj) + mc_cp_stats = cp_stats_peer_obj->peer_stats; + + peer_cp_stat_prv = + wlan_cp_stats_get_peer_stats_obj(peer); + + if (peer_cp_stat_prv && mc_cp_stats) { + wlan_cp_stats_peer_obj_lock(peer_cp_stat_prv); + ucfg_twt_get_peer_session_param(mc_cp_stats, + params, + &num_twt_session); + wlan_cp_stats_peer_obj_unlock(peer_cp_stat_prv); } + + if (opmode == QDF_STA_MODE && + num_twt_session >= TWT_PEER_MAX_SESSIONS) + goto done; + + if (opmode == QDF_SAP_MODE && + num_twt_session >= (sap_max_peer * TWT_PEER_MAX_SESSIONS)) + goto done; + + peer_next = wlan_peer_get_next_active_peer_of_vdev( + vdev, peer_list, peer, + WLAN_CP_STATS_ID); + peer = peer_next; } done: - /* If atleast one peer with valid twt session is found return success */ - if (num_sessions) - qdf_status = QDF_STATUS_SUCCESS; - else - qdf_err("Unable to find a peer with twt session established"); + if (!num_twt_session) + cp_stats_err("Unable to find a peer with twt session established"); - qdf_spin_unlock_bh(&peer_list->peer_list_lock); - wlan_psoc_obj_unlock(psoc_obj); - return qdf_status; + wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID); + return num_twt_session; } -QDF_STATUS +int ucfg_twt_get_peer_session_params(struct wlan_objmgr_psoc *psoc_obj, struct wmi_host_twt_session_stats_info *params) { uint8_t *mac_addr; uint32_t dialog_id; + uint8_t vdev_id; + int num_twt_session = 0; if (!psoc_obj || !params) - return QDF_STATUS_E_INVAL; + return num_twt_session; mac_addr = params[0].peer_mac; dialog_id = params[0].dialog_id; + vdev_id = params[0].vdev_id; /* * Currently for STA case, twt_get_params nl is sending only dialog_id @@ -284,14 +299,18 @@ ucfg_twt_get_peer_session_params(struct wlan_objmgr_psoc *psoc_obj, * ucfg_twt_get_peer_session_params. */ if (!QDF_IS_ADDR_BROADCAST(mac_addr)) - return ucfg_twt_get_single_peer_session_params(psoc_obj, - mac_addr, - dialog_id, - params); + num_twt_session = ucfg_twt_get_single_peer_session_params( + psoc_obj, + mac_addr, + dialog_id, + params); else - return ucfg_twt_get_all_peer_session_params(psoc_obj, params); + num_twt_session = ucfg_twt_get_all_peer_session_params( + psoc_obj, + vdev_id, + params); - return QDF_STATUS_E_INVAL; + return num_twt_session; } #endif /* WLAN_SUPPORT_TWT */ diff --git a/core/hdd/src/wlan_hdd_twt.c b/core/hdd/src/wlan_hdd_twt.c index 37574f582924..57ba7e22a25b 100644 --- a/core/hdd/src/wlan_hdd_twt.c +++ b/core/hdd/src/wlan_hdd_twt.c @@ -481,6 +481,12 @@ static uint32_t hdd_twt_get_params_resp_len(void) /* QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATE */ len += nla_total_size(sizeof(u32)); + /* QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE */ + len += nla_total_size(sizeof(u8)); + + /* QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL2_MANTISSA */ + len += nla_total_size(sizeof(u32)); + return len; } @@ -511,13 +517,16 @@ hdd_get_converted_twt_state(enum wlan_twt_session_state state) * @psoc: Pointer to Global psoc * @reply_skb: pointer to response skb buffer * @params: Ponter to twt peer session parameters + * @num_twt_session: total number of valid twt session * * Return: QDF_STATUS_SUCCESS on success, else other qdf error values */ static QDF_STATUS -hdd_twt_pack_get_params_resp_nlmsg(struct wlan_objmgr_psoc *psoc, - struct sk_buff *reply_skb, - struct wmi_host_twt_session_stats_info *params) +hdd_twt_pack_get_params_resp_nlmsg( + struct wlan_objmgr_psoc *psoc, + struct sk_buff *reply_skb, + struct wmi_host_twt_session_stats_info *params, + int num_twt_session) { struct nlattr *config_attr, *nla_params; enum wlan_twt_session_state state; @@ -534,7 +543,7 @@ hdd_twt_pack_get_params_resp_nlmsg(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_INVAL; } - for (i = 0; i < TWT_PSOC_MAX_SESSIONS; i++) { + for (i = 0; i < num_twt_session; i++) { if (params[i].event_type != HOST_TWT_SESSION_SETUP && params[i].event_type != HOST_TWT_SESSION_UPDATE) continue; @@ -665,12 +674,14 @@ hdd_twt_pack_get_params_resp_nlmsg(struct wlan_objmgr_psoc *psoc, * and sends response to the user space via nl layer * @hdd_ctx: hdd context * @params: Pointer to store twt peer session parameters + * @num_twt_session: number of twt session * * Return: QDF_STATUS_SUCCESS on success, else other qdf error values */ static QDF_STATUS hdd_twt_pack_get_params_resp(struct hdd_context *hdd_ctx, - struct wmi_host_twt_session_stats_info *params) + struct wmi_host_twt_session_stats_info *params, + int num_twt_session) { struct sk_buff *reply_skb; uint32_t skb_len = NLMSG_HDRLEN, i; @@ -680,7 +691,7 @@ hdd_twt_pack_get_params_resp(struct hdd_context *hdd_ctx, skb_len += NLA_HDRLEN; /* Length of twt session parameters */ - for (i = 0; i < TWT_PSOC_MAX_SESSIONS; i++) { + for (i = 0; i < num_twt_session; i++) { if (params[i].event_type == HOST_TWT_SESSION_SETUP || params[i].event_type == HOST_TWT_SESSION_UPDATE) skb_len += hdd_twt_get_params_resp_len(); @@ -694,7 +705,8 @@ hdd_twt_pack_get_params_resp(struct hdd_context *hdd_ctx, } qdf_status = hdd_twt_pack_get_params_resp_nlmsg(hdd_ctx->psoc, - reply_skb, params); + reply_skb, params, + num_twt_session); if (QDF_IS_STATUS_ERROR(qdf_status)) goto fail; @@ -749,7 +761,7 @@ hdd_send_inactive_session_reply(struct hdd_adapter *adapter, QDF_STATUS qdf_status; params[0].event_type = HOST_TWT_SESSION_UPDATE; - qdf_status = hdd_twt_pack_get_params_resp(adapter->hdd_ctx, params); + qdf_status = hdd_twt_pack_get_params_resp(adapter->hdd_ctx, params, 0); return qdf_status; } @@ -766,14 +778,17 @@ static QDF_STATUS hdd_twt_get_peer_session_params(struct hdd_context *hdd_ctx, struct wmi_host_twt_session_stats_info *params) { + int num_twt_session = 0; QDF_STATUS qdf_status = QDF_STATUS_E_INVAL; if (!hdd_ctx || !params) return qdf_status; - qdf_status = ucfg_twt_get_peer_session_params(hdd_ctx->psoc, params); - if (QDF_IS_STATUS_SUCCESS(qdf_status)) - qdf_status = hdd_twt_pack_get_params_resp(hdd_ctx, params); + num_twt_session = ucfg_twt_get_peer_session_params(hdd_ctx->psoc, + params); + if (num_twt_session) + qdf_status = hdd_twt_pack_get_params_resp(hdd_ctx, params, + num_twt_session); return qdf_status; } @@ -789,11 +804,12 @@ hdd_twt_get_peer_session_params(struct hdd_context *hdd_ctx, static int hdd_sap_twt_get_session_params(struct hdd_adapter *adapter, struct nlattr *twt_param_attr) { + struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1]; - struct wmi_host_twt_session_stats_info - params[TWT_PSOC_MAX_SESSIONS] = { {0} }; + int max_num_peer; + struct wmi_host_twt_session_stats_info *params; int ret, id, id1; - QDF_STATUS qdf_status; + QDF_STATUS qdf_status = QDF_STATUS_E_INVAL; struct qdf_mac_addr mac_addr; bool is_associated; @@ -804,6 +820,11 @@ static int hdd_sap_twt_get_session_params(struct hdd_adapter *adapter, if (ret) return ret; + max_num_peer = hdd_ctx->wiphy->max_ap_assoc_sta; + params = qdf_mem_malloc(TWT_PEER_MAX_SESSIONS * max_num_peer * + sizeof(*params)); + + params[0].vdev_id = adapter->vdev_id; id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID; id1 = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAC_ADDR; @@ -812,13 +833,13 @@ static int hdd_sap_twt_get_session_params(struct hdd_adapter *adapter, nla_memcpy(params[0].peer_mac, tb[id1], QDF_MAC_ADDR_SIZE); } else { hdd_err_rl("TWT: get_params dialog_id or mac_addr is missing"); - return -EINVAL; + goto done; } if (QDF_IS_ADDR_BROADCAST(params[0].peer_mac) && params[0].dialog_id != TWT_ALL_SESSIONS_DIALOG_ID) { hdd_err_rl("TWT: get_params dialog_is is invalid"); - return -EINVAL; + goto done; } if (!params[0].dialog_id) @@ -832,7 +853,7 @@ static int hdd_sap_twt_get_session_params(struct hdd_adapter *adapter, hdd_err("TWT: Association doesn't exist for STA: " QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(&mac_addr)); - return -EINVAL; + goto done; } } @@ -841,7 +862,8 @@ static int hdd_sap_twt_get_session_params(struct hdd_adapter *adapter, qdf_status = hdd_twt_get_peer_session_params(adapter->hdd_ctx, ¶ms[0]); - +done: + qdf_mem_free(params); return qdf_status_to_os_return(qdf_status); } @@ -872,6 +894,7 @@ static int hdd_sta_twt_get_session_params(struct hdd_adapter *adapter, if (ret) return ret; + params[0].vdev_id = adapter->vdev_id; /* * Currently twt_get_params nl cmd is sending only dialog_id(STA), fill * mac_addr of STA in params and call hdd_twt_get_peer_session_params. @@ -2897,8 +2920,8 @@ static uint32_t get_session_wake_duration(struct hdd_context *hdd_ctx, uint32_t dialog_id, struct qdf_mac_addr *peer_macaddr) { - QDF_STATUS qdf_status; struct wmi_host_twt_session_stats_info params = {0}; + int num_twt_session = 0; params.dialog_id = dialog_id; qdf_mem_copy(params.peer_mac, @@ -2907,8 +2930,9 @@ static uint32_t get_session_wake_duration(struct hdd_context *hdd_ctx, hdd_debug("Get_params peer mac_addr " QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(params.peer_mac)); - qdf_status = ucfg_twt_get_peer_session_params(hdd_ctx->psoc, ¶ms); - if (QDF_IS_STATUS_SUCCESS(qdf_status)) + num_twt_session = ucfg_twt_get_peer_session_params(hdd_ctx->psoc, + ¶ms); + if (num_twt_session) return params.wake_dura_us; return 0;