diff --git a/os_if/linux/qca_vendor.h b/os_if/linux/qca_vendor.h index fe2e783a2a81..ef9db55aa4a1 100644 --- a/os_if/linux/qca_vendor.h +++ b/os_if/linux/qca_vendor.h @@ -770,9 +770,10 @@ enum qca_wlan_vendor_attr_get_station_info { QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_STBC, QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_CH_WIDTH, QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_SGI_ENABLE, -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)) QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_PAD, -#endif + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_RETRY_COUNT, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_BC_MC_COUNT, + /* keep last */ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AFTER_LAST, QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_MAX = diff --git a/target_if/cp_stats/src/target_if_mc_cp_stats.c b/target_if/cp_stats/src/target_if_mc_cp_stats.c index 6886b3051720..c91f50ae737c 100644 --- a/target_if/cp_stats/src/target_if_mc_cp_stats.c +++ b/target_if/cp_stats/src/target_if_mc_cp_stats.c @@ -43,6 +43,8 @@ static void target_if_cp_stats_free_stats_event(struct stats_event *ev) ev->peer_stats = NULL; qdf_mem_free(ev->peer_adv_stats); ev->peer_adv_stats = NULL; + qdf_mem_free(ev->peer_extended_stats); + ev->peer_extended_stats = NULL; qdf_mem_free(ev->cca_stats); ev->cca_stats = NULL; qdf_mem_free(ev->vdev_summary_stats); @@ -86,6 +88,43 @@ static QDF_STATUS target_if_cp_stats_extract_pdev_stats( return QDF_STATUS_SUCCESS; } +static void target_if_cp_stats_extract_peer_extd_stats( + struct wmi_unified *wmi_hdl, + wmi_host_stats_event *stats_param, + struct stats_event *ev, + uint8_t *data) + +{ + QDF_STATUS status; + uint32_t i; + wmi_host_peer_extd_stats peer_extd_stats; + + if (!stats_param->num_peer_extd_stats) + return; + + ev->peer_extended_stats = + qdf_mem_malloc(sizeof(*ev->peer_extended_stats) * + stats_param->num_peer_extd_stats); + if (!ev->peer_extended_stats) + return; + + ev->num_peer_extd_stats = stats_param->num_peer_extd_stats; + + for (i = 0; i < ev->num_peer_extd_stats; i++) { + status = wmi_extract_peer_extd_stats(wmi_hdl, data, i, + &peer_extd_stats); + if (QDF_IS_STATUS_ERROR(status)) { + cp_stats_err("wmi_extract_peer_extd_stats failed"); + continue; + } + WMI_MAC_ADDR_TO_CHAR_ARRAY( + &peer_extd_stats.peer_macaddr, + ev->peer_extended_stats[i].peer_macaddr); + ev->peer_extended_stats[i].rx_mc_bc_cnt = + peer_extd_stats.rx_mc_bc_cnt; + } +} + static QDF_STATUS target_if_cp_stats_extract_peer_stats( struct wmi_unified *wmi_hdl, wmi_host_stats_event *stats_param, @@ -99,14 +138,14 @@ static QDF_STATUS target_if_cp_stats_extract_peer_stats( struct wmi_host_peer_adv_stats *peer_adv_stats; /* Extract peer_stats */ - ev->num_peer_stats = stats_param->num_peer_stats; - if (!ev->num_peer_stats) + if (!stats_param->num_peer_stats) return QDF_STATUS_SUCCESS; ev->peer_stats = qdf_mem_malloc(sizeof(*ev->peer_stats) * - ev->num_peer_stats); + stats_param->num_peer_stats); if (!ev->peer_stats) return QDF_STATUS_E_NOMEM; + ev->num_peer_stats = stats_param->num_peer_stats; db2dbm_enabled = wmi_service_enabled(wmi_hdl, wmi_service_hw_db2dbm_support); @@ -127,6 +166,9 @@ static QDF_STATUS target_if_cp_stats_extract_peer_stats( TGT_NOISE_FLOOR_DBM; } + target_if_cp_stats_extract_peer_extd_stats(wmi_hdl, stats_param, ev, + data); + /* Extract peer_adv_stats */ ev->num_peer_adv_stats = stats_param->num_peer_adv_stats; if (!ev->num_peer_adv_stats) @@ -540,7 +582,7 @@ static uint32_t get_stats_id(enum stats_req_type type) case TYPE_CONNECTION_TX_POWER: return WMI_REQUEST_PDEV_STAT; case TYPE_PEER_STATS: - return WMI_REQUEST_PEER_STAT; + return WMI_REQUEST_PEER_STAT | WMI_REQUEST_PEER_EXTD_STAT; case TYPE_STATION_STATS: return (WMI_REQUEST_AP_STAT | WMI_REQUEST_PEER_STAT | diff --git a/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h b/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h index 4010f4b29a5b..43efd71f18de 100644 --- a/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h +++ b/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h @@ -222,6 +222,16 @@ QDF_STATUS wlan_crypto_demic(struct wlan_objmgr_vdev *vdev, */ bool wlan_crypto_vdev_is_pmf_enabled(struct wlan_objmgr_vdev *vdev); +/** + * wlan_crypto_vdev_is_pmf_required - called to check is pmf required in vdev + * @vdev: vdev + * + * This function gets called to check is pmf required or not in vdev. + * + * Return: true or false + */ +bool wlan_crypto_vdev_is_pmf_required(struct wlan_objmgr_vdev *vdev); + /** * wlan_crypto_is_pmf_enabled - called by mgmt txrx to check is pmf enabled * @vdev: vdev diff --git a/umac/cmn_services/crypto/src/wlan_crypto_global_api.c b/umac/cmn_services/crypto/src/wlan_crypto_global_api.c index cbdc095ef5db..5bc4b007bf4a 100644 --- a/umac/cmn_services/crypto/src/wlan_crypto_global_api.c +++ b/umac/cmn_services/crypto/src/wlan_crypto_global_api.c @@ -394,8 +394,11 @@ QDF_STATUS wlan_crypto_set_del_pmksa(struct wlan_objmgr_vdev *vdev, QDF_STATUS status = QDF_STATUS_E_INVAL; struct wlan_crypto_comp_priv *crypto_priv; struct wlan_crypto_params *crypto_params; + enum QDF_OPMODE op_mode; - if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) + op_mode = wlan_vdev_mlme_get_opmode(vdev); + + if (op_mode != QDF_STA_MODE && op_mode != QDF_SAP_MODE) return QDF_STATUS_E_NOSUPPORT; if (!pmksa && set) { @@ -1642,6 +1645,36 @@ bool wlan_crypto_vdev_is_pmf_enabled(struct wlan_objmgr_vdev *vdev) return false; } + +/** + * wlan_crypto_vdev_is_pmf_required - called to check is pmf required in vdev + * @vdev: vdev + * + * This function gets called to check is pmf required or not in vdev. + * + * Return: true or false + */ +bool wlan_crypto_vdev_is_pmf_required(struct wlan_objmgr_vdev *vdev) +{ + struct wlan_crypto_comp_priv *crypto_priv; + struct wlan_crypto_params *vdev_crypto_params; + + if (!vdev) + return false; + + vdev_crypto_params = wlan_crypto_vdev_get_comp_params(vdev, + &crypto_priv); + if (!crypto_priv) { + crypto_err("crypto_priv NULL"); + return QDF_STATUS_E_INVAL; + } + + if (vdev_crypto_params->rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED) + return true; + + return false; +} + /** * wlan_crypto_is_pmf_enabled - called by mgmt txrx to check is pmf enabled * @vdev: vdev @@ -2805,7 +2838,7 @@ bool wlan_crypto_rsn_info(struct wlan_objmgr_vdev *vdev, crypto_debug("Key mgmt match failed"); return false; } - if (wlan_crypto_vdev_is_pmf_enabled(vdev) && + if (wlan_crypto_vdev_is_pmf_required(vdev) && !(crypto_params->rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_ENABLED)) { crypto_debug("Peer is not PMF capable"); return false; diff --git a/umac/cp_stats/core/src/wlan_cp_stats_defs.h b/umac/cp_stats/core/src/wlan_cp_stats_defs.h index dcad1b24f1ad..4381cfa687f0 100644 --- a/umac/cp_stats/core/src/wlan_cp_stats_defs.h +++ b/umac/cp_stats/core/src/wlan_cp_stats_defs.h @@ -88,6 +88,7 @@ struct vdev_cp_stats { * @peer_obj: pointer to peer * @peer_stats: pointer to ic/mc specific stats * @peer_adv_stats: pointer to peer adv stats + * @peer_extd_stats: Pointer to peer extended stats * @peer_comp_priv_obj[]: component's private object pointers * @peer_cp_stats_lock: lock to protect object */ @@ -95,6 +96,7 @@ struct peer_cp_stats { struct wlan_objmgr_peer *peer_obj; void *peer_stats; void *peer_adv_stats; + void *peer_extd_stats; void *peer_comp_priv_obj[WLAN_CP_STATS_MAX_COMPONENTS]; qdf_spinlock_t peer_cp_stats_lock; }; diff --git a/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h b/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h index b5138e808dea..357b86244ec5 100644 --- a/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h +++ b/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h @@ -237,6 +237,28 @@ struct vdev_mc_cp_stats { struct summary_stats vdev_summary_stats; }; +/** + * struct peer_extd_stats - Peer extension statistics + * @peer_macaddr: peer MAC address + * @rx_duration: lower 32 bits of rx duration in microseconds + * @peer_tx_bytes: Total TX bytes (including dot11 header) sent to peer + * @peer_rx_bytes: Total RX bytes (including dot11 header) received from peer + * @last_tx_rate_code: last TX ratecode + * @last_tx_power: TX power used by peer - units are 0.5 dBm + * @rx_mc_bc_cnt: Total number of received multicast & broadcast data frames + * corresponding to this peer, 1 in the MSB of rx_mc_bc_cnt represents a + * valid data + */ +struct peer_extd_stats { + uint8_t peer_macaddr[QDF_MAC_ADDR_SIZE]; + uint32_t rx_duration; + uint32_t peer_tx_bytes; + uint32_t peer_rx_bytes; + uint32_t last_tx_rate_code; + int32_t last_tx_power; + uint32_t rx_mc_bc_cnt; +}; + /** * struct peer_mc_cp_stats - peer specific stats * @tx_rate: tx rate @@ -303,6 +325,8 @@ struct chain_rssi_event { * @peer_stats: if populated array indicating peer stats * @peer_adv_stats: if populated, indicates peer adv (extd2) stats * @num_peer_adv_stats: number of peer adv (extd2) stats + * @num_peer_extd_stats: Num peer extended stats + * @peer_extended_stats: Peer extended stats * @cca_stats: if populated indicates congestion stats * @num_summary_stats: number of summary stats * @vdev_summary_stats: if populated indicates array of summary stats per vdev @@ -320,6 +344,8 @@ struct stats_event { struct peer_mc_cp_stats *peer_stats; uint32_t num_peer_adv_stats; struct peer_adv_mc_cp_stats *peer_adv_stats; + uint32_t num_peer_extd_stats; + struct peer_extd_stats *peer_extended_stats; struct congestion_stats_event *cca_stats; uint32_t num_summary_stats; struct summary_stats_event *vdev_summary_stats; diff --git a/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_tgt_api.c b/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_tgt_api.c index 03dcc7463401..edad12c386d0 100644 --- a/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_tgt_api.c +++ b/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_tgt_api.c @@ -115,6 +115,7 @@ static void peer_rssi_iterator(struct wlan_objmgr_pdev *pdev, struct stats_event *ev; struct peer_mc_cp_stats *peer_mc_stats; struct peer_cp_stats *peer_cp_stats_priv; + struct peer_extd_stats *peer_extd_mc_stats; if (WLAN_PEER_SELF == wlan_peer_get_peer_type(peer)) { cp_stats_err("ignore self peer: %pM", @@ -133,6 +134,10 @@ static void peer_rssi_iterator(struct wlan_objmgr_pdev *pdev, ev = arg; ev->peer_stats[ev->num_peer_stats] = *peer_mc_stats; ev->num_peer_stats++; + + peer_extd_mc_stats = peer_cp_stats_priv->peer_extd_stats; + ev->peer_extended_stats[ev->num_peer_extd_stats] = *peer_extd_mc_stats; + ev->num_peer_extd_stats++; wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv); } @@ -147,6 +152,7 @@ tgt_mc_cp_stats_prepare_raw_peer_rssi(struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_vdev *vdev; struct wlan_objmgr_peer *peer = NULL; struct peer_mc_cp_stats *peer_mc_stats; + struct peer_extd_stats *peer_mc_extd_stats; struct peer_cp_stats *peer_cp_stats_priv; void (*get_peer_rssi_cb)(struct stats_event *ev, void *cookie); @@ -172,6 +178,12 @@ tgt_mc_cp_stats_prepare_raw_peer_rssi(struct wlan_objmgr_psoc *psoc, if (!ev.peer_stats) goto end; + ev.peer_extended_stats = + qdf_mem_malloc(sizeof(*ev.peer_extended_stats) * + peer_count); + if (!ev.peer_extended_stats) + goto end; + wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_PEER_OP, peer_rssi_iterator, &ev, true, WLAN_CP_STATS_ID); @@ -194,9 +206,20 @@ tgt_mc_cp_stats_prepare_raw_peer_rssi(struct wlan_objmgr_psoc *psoc, goto end; ev.num_peer_stats = 1; + + ev.peer_extended_stats = + qdf_mem_malloc(sizeof(*ev.peer_extended_stats)); + if (!ev.peer_extended_stats) + goto end; + + ev.num_peer_extd_stats = 1; + wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv); peer_mc_stats = peer_cp_stats_priv->peer_stats; *ev.peer_stats = *peer_mc_stats; + + peer_mc_extd_stats = peer_cp_stats_priv->peer_extd_stats; + *ev.peer_extended_stats = *peer_mc_extd_stats; wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv); } @@ -299,8 +322,7 @@ tgt_mc_cp_stats_update_peer_stats(struct wlan_objmgr_psoc *psoc, peer_mc_stats->rx_rate = peer_stats->rx_rate; if (peer_stats->peer_rssi) peer_mc_stats->peer_rssi = peer_stats->peer_rssi; - - cp_stats_debug("peer_mac=%pM, tx_rate=%u, rx_rate=%u, peer_rssi=%u", + cp_stats_debug("peer_mac=%pM, tx_rate=%u, rx_rate=%u, peer_rssi=%d", peer_mc_stats->peer_macaddr, peer_mc_stats->tx_rate, peer_mc_stats->rx_rate, peer_mc_stats->peer_rssi); wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv); @@ -312,6 +334,103 @@ end: return status; } +static QDF_STATUS +tgt_mc_cp_stats_update_peer_extd_stats( + struct wlan_objmgr_psoc *psoc, + struct peer_extd_stats *peer_extended_stats) +{ + uint8_t *peer_mac_addr; + struct wlan_objmgr_peer *peer; + struct peer_extd_stats *peer_extd_mc_stats; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct peer_cp_stats *peer_cp_stats_priv; + + if (!peer_extended_stats) + return QDF_STATUS_E_INVAL; + + peer_mac_addr = peer_extended_stats->peer_macaddr; + peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac_addr, + WLAN_CP_STATS_ID); + if (!peer) { + cp_stats_err("peer is null"); + return QDF_STATUS_E_EXISTS; + } + + peer_cp_stats_priv = wlan_cp_stats_get_peer_stats_obj(peer); + if (!peer_cp_stats_priv) { + cp_stats_err("peer_cp_stats_priv is null"); + status = QDF_STATUS_E_EXISTS; + goto end; + } + + wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv); + peer_extd_mc_stats = peer_cp_stats_priv->peer_extd_stats; + if (!peer_extd_mc_stats) { + wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv); + cp_stats_err("No peer_extd_mc_stats"); + status = QDF_STATUS_E_INVAL; + goto end; + } + qdf_mem_copy(peer_extd_mc_stats->peer_macaddr, + peer_extended_stats->peer_macaddr, + QDF_MAC_ADDR_SIZE); + if (peer_extended_stats->rx_mc_bc_cnt) + peer_extd_mc_stats->rx_mc_bc_cnt = + peer_extended_stats->rx_mc_bc_cnt; + wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv); + + cp_stats_debug("peer_mac=%pM, rx_mc_bc_cnt=%u", + peer_extended_stats->peer_macaddr, + peer_extended_stats->rx_mc_bc_cnt); + +end: + wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID); + + return status; +} + +static void tgt_mc_cp_stats_extract_peer_extd_stats( + struct wlan_objmgr_psoc *psoc, + struct stats_event *ev) +{ + uint32_t i, selected; + QDF_STATUS status; + struct request_info last_req = {0}; + + status = ucfg_mc_cp_stats_get_pending_req(psoc, + TYPE_PEER_STATS, + &last_req); + + if (QDF_IS_STATUS_ERROR(status)) { + cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed"); + return; + } + + selected = ev->num_peer_extd_stats; + for (i = 0; i < ev->num_peer_extd_stats; i++) { + status = tgt_mc_cp_stats_update_peer_extd_stats( + psoc, + &ev->peer_extended_stats[i]); + if (!QDF_IS_ADDR_BROADCAST(last_req.peer_mac_addr) && + !qdf_mem_cmp(ev->peer_stats[i].peer_macaddr, + last_req.peer_mac_addr, + QDF_MAC_ADDR_SIZE)) { + /* mac is specified, but failed to update the peer */ + if (QDF_IS_STATUS_ERROR(status)) + return; + + selected = i; + } + } + + /* no matched peer */ + if (!QDF_IS_ADDR_BROADCAST(last_req.peer_mac_addr) && + selected == ev->num_peer_extd_stats) { + cp_stats_err("peer not found stats"); + return; + } +} + static void tgt_mc_cp_stats_extract_peer_stats(struct wlan_objmgr_psoc *psoc, struct stats_event *ev, bool is_station_stats) @@ -397,6 +516,7 @@ complete: if (is_station_stats) return; + tgt_mc_cp_stats_extract_peer_extd_stats(psoc, ev); tgt_mc_cp_stats_prepare_raw_peer_rssi(psoc, &last_req); ucfg_mc_cp_stats_reset_pending_req(psoc, TYPE_PEER_STATS); } diff --git a/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c b/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c index def4b8c95615..409c4d8d087c 100644 --- a/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c +++ b/umac/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c @@ -88,10 +88,19 @@ QDF_STATUS wlan_cp_stats_peer_cs_init(struct peer_cp_stats *peer_cs) peer_cs->peer_adv_stats = qdf_mem_malloc(sizeof (struct peer_adv_mc_cp_stats)); if (!peer_cs->peer_adv_stats) { - cp_stats_err("malloc failed"); qdf_mem_free(peer_cs->peer_stats); return QDF_STATUS_E_NOMEM; } + + peer_cs->peer_extd_stats = + qdf_mem_malloc(sizeof(struct peer_extd_stats)); + if (!peer_cs->peer_extd_stats) { + qdf_mem_free(peer_cs->peer_stats); + peer_cs->peer_stats = NULL; + qdf_mem_free(peer_cs->peer_adv_stats); + peer_cs->peer_adv_stats = NULL; + return QDF_STATUS_E_NOMEM; + } return QDF_STATUS_SUCCESS; } @@ -99,8 +108,11 @@ QDF_STATUS wlan_cp_stats_peer_cs_deinit(struct peer_cp_stats *peer_cs) { qdf_mem_free(peer_cs->peer_adv_stats); peer_cs->peer_adv_stats = NULL; + qdf_mem_free(peer_cs->peer_extd_stats); + peer_cs->peer_extd_stats = NULL; qdf_mem_free(peer_cs->peer_stats); peer_cs->peer_stats = NULL; + return QDF_STATUS_SUCCESS; } @@ -568,6 +580,7 @@ void ucfg_mc_cp_stats_free_stats_resources(struct stats_event *ev) qdf_mem_free(ev->cca_stats); qdf_mem_free(ev->vdev_summary_stats); qdf_mem_free(ev->vdev_chain_rssi); + qdf_mem_free(ev->peer_extended_stats); qdf_mem_zero(ev, sizeof(*ev)); } diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index daf37a880ecf..69df9b04a118 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -4083,6 +4083,8 @@ struct rx_reorder_queue_remove_params { * @num_pdev_ext_stats: number of pdev ext stats event structures * @num_vdev_stats: number of vdev stats * @num_peer_stats: number of peer stats event structures 0 or max peers + * @num_peer_extd_stats: number of peer extended stats event structures 0 + * or max peers * @num_bcnflt_stats: number of beacon filter stats * @num_chan_stats: number of channel stats * @pdev_id: device id for the radio @@ -4097,6 +4099,7 @@ typedef struct { uint32_t num_pdev_ext_stats; uint32_t num_vdev_stats; uint32_t num_peer_stats; + uint32_t num_peer_extd_stats; uint32_t num_bcnflt_stats; uint32_t num_chan_stats; uint32_t pdev_id; @@ -4119,7 +4122,10 @@ typedef struct { * @atf_tokens_utilized: atf tokens utilized * @num_mu_tx_blacklisted: Blacklisted MU Tx count * @sgi_count: sgi count of the peer - * @reserved: for future use + * @rx_mc_bc_cnt: Total number of received multicast & broadcast data frames + * corresponding to this peer, 1 in the MSB of rx_mc_bc_cnt represents a + * valid data + * @rx_retry_cnt: Number of rx retries received from current station */ typedef struct { wmi_host_mac_addr peer_macaddr; @@ -4133,7 +4139,8 @@ typedef struct { uint32_t atf_tokens_utilized; uint32_t num_mu_tx_blacklisted; uint32_t sgi_count; - uint32_t reserved[2]; + uint32_t rx_mc_bc_cnt; + uint32_t rx_retry_cnt; } wmi_host_peer_extd_stats; /** diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 2ed7493a8b62..433238246d58 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -8341,6 +8341,9 @@ static QDF_STATUS extract_all_stats_counts_tlv(wmi_unified_t wmi_handle, case WMI_REQUEST_BCN_STAT: stats_param->stats_id |= WMI_HOST_REQUEST_BCN_STAT; break; + case WMI_REQUEST_PEER_EXTD_STAT: + stats_param->stats_id |= WMI_REQUEST_PEER_EXTD_STAT; + break; case WMI_REQUEST_PEER_EXTD2_STAT: stats_param->stats_id |= WMI_HOST_REQUEST_PEER_ADV_STATS; @@ -8377,6 +8380,7 @@ static QDF_STATUS extract_all_stats_counts_tlv(wmi_unified_t wmi_handle, stats_param->num_pdev_ext_stats = 0; stats_param->num_vdev_stats = ev->num_vdev_stats; stats_param->num_peer_stats = ev->num_peer_stats; + stats_param->num_peer_extd_stats = ev->num_peer_extd_stats; stats_param->num_bcnflt_stats = ev->num_bcnflt_stats; stats_param->num_chan_stats = ev->num_chan_stats; stats_param->num_bcn_stats = ev->num_bcn_stats; @@ -8821,7 +8825,37 @@ static QDF_STATUS extract_peer_extd_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, uint32_t index, wmi_host_peer_extd_stats *peer_extd_stats) { + WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf; + wmi_stats_event_fixed_param *ev_param; + uint8_t *data; + + param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf; + ev_param = (wmi_stats_event_fixed_param *)param_buf->fixed_param; + data = (uint8_t *)param_buf->data; + if (!data) + return QDF_STATUS_E_FAILURE; + + if (index < ev_param->num_peer_extd_stats) { + wmi_peer_extd_stats *ev = (wmi_peer_extd_stats *) (data + + (ev_param->num_pdev_stats * sizeof(wmi_pdev_stats)) + + (ev_param->num_vdev_stats * sizeof(wmi_vdev_stats)) + + (ev_param->num_peer_stats * sizeof(wmi_peer_stats)) + + (ev_param->num_bcnflt_stats * + sizeof(wmi_bcnfilter_stats_t)) + + (ev_param->num_chan_stats * sizeof(wmi_chan_stats)) + + (ev_param->num_mib_stats * sizeof(wmi_mib_stats)) + + (ev_param->num_bcn_stats * sizeof(wmi_bcn_stats)) + + (index * sizeof(wmi_peer_extd_stats))); + + qdf_mem_zero(peer_extd_stats, sizeof(wmi_host_peer_extd_stats)); + qdf_mem_copy(&peer_extd_stats->peer_macaddr, &ev->peer_macaddr, + sizeof(wmi_mac_addr)); + + peer_extd_stats->rx_mc_bc_cnt = ev->rx_mc_bc_cnt; + } + return QDF_STATUS_SUCCESS; + } /**