diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h index 291448d122..3e7ca3c20b 100644 --- a/dp/inc/cdp_txrx_cmn_struct.h +++ b/dp/inc/cdp_txrx_cmn_struct.h @@ -1622,7 +1622,7 @@ struct cdp_tx_completion_msdu { * @peer_id: Peer ID * @vdev_id: VAP ID * @is_ampdu: mpdu aggregate or non-aggregate? - * @ofdma_info_valid: RU info valid + * @mu_ul_info_valid: MU UL info valid * @ofdma_ru_start_index: RU index number(0-73) * @ofdma_ru_width: size of RU in units of 1(26tone)RU * @nss: NSS 1,2, ...8 @@ -1652,7 +1652,7 @@ struct cdp_rx_stats_ppdu_user { uint16_t peer_id; uint8_t vdev_id; bool is_ampdu; - uint32_t ofdma_info_valid:1, + uint32_t mu_ul_info_valid:1, ofdma_ru_start_index:7, ofdma_ru_width:7, nss:4, @@ -1661,6 +1661,7 @@ struct cdp_rx_stats_ppdu_user { uint8_t user_index; uint32_t ast_index; uint32_t tid; + uint32_t num_msdu; uint16_t tcp_msdu_count; uint16_t udp_msdu_count; uint16_t other_msdu_count; diff --git a/dp/inc/cdp_txrx_stats_struct.h b/dp/inc/cdp_txrx_stats_struct.h index 71f3794823..a7a1eee27d 100644 --- a/dp/inc/cdp_txrx_stats_struct.h +++ b/dp/inc/cdp_txrx_stats_struct.h @@ -195,6 +195,18 @@ enum cdp_packet_type { DOT11_MAX = 5, }; +/* + * cdp_mu_packet_type: MU Rx type index + * RX_TYPE_MU_MIMO: MU MIMO Rx type index + * RX_TYPE_MU_OFDMA: MU OFDMA Rx type index + * MU_MIMO_OFDMA: MU Rx MAX type index + */ +enum cdp_mu_packet_type { + RX_TYPE_MU_MIMO = 0, + RX_TYPE_MU_OFDMA = 1, + RX_TYPE_MU_MAX = 2, +}; + enum WDI_EVENT { WDI_EVENT_TX_STATUS = WDI_EVENT_BASE, WDI_EVENT_OFFLOAD_ALL, @@ -445,6 +457,20 @@ struct cdp_pkt_type { uint32_t mcs_count[MAX_MCS]; }; +/* + * struct cdp_rx_mu - Rx MU Stats + * @ppdu_nss[SS_COUNT]: Packet Count in spatial streams + * @mpdu_cnt_fcs_ok: Rx success mpdu count + * @mpdu_cnt_fcs_err: Rx fail mpdu count + * @cdp_pkt_type: counter array for each MCS index + */ +struct cdp_rx_mu { + uint32_t ppdu_nss[SS_COUNT]; + uint32_t mpdu_cnt_fcs_ok; + uint32_t mpdu_cnt_fcs_err; + struct cdp_pkt_type ppdu; +}; + /* struct cdp_tx_pkt_info - tx packet info * num_msdu - successful msdu * num_mpdu - successful mpdu from compltn common @@ -706,7 +732,13 @@ struct cdp_tx_stats { * @reception_type[MAX_RECEPTION_TYPES]: Reception type os packets * @mcs_count[MAX_MCS]: mcs count * @sgi_count[MAX_GI]: sgi count - * @nss[SS_COUNT]: Packet count in spatiel Streams + * @nss[SS_COUNT]: packet count in spatiel Streams + * @ppdu_nss[SS_COUNT]: PPDU packet count in spatial streams + * @mpdu_cnt_fcs_ok: SU Rx success mpdu count + * @mpdu_cnt_fcs_err: SU Rx fail mpdu count + * @su_ax_ppdu_cnt: SU Rx packet count + * @ppdu_cnt[MAX_RECEPTION_TYPES]: PPDU packet count in reception type + * @rx_mu[RX_TYPE_MU_MAX]: Rx MU stats * @bw[MAX_BW]: Packet Count in different bandwidths * @non_ampdu_cnt: Number of MSDUs with no MPDU level aggregation * @ampdu_cnt: Number of MSDUs part of AMSPU @@ -767,6 +799,12 @@ struct cdp_rx_stats { struct cdp_pkt_type pkt_type[DOT11_MAX]; uint32_t sgi_count[MAX_GI]; uint32_t nss[SS_COUNT]; + uint32_t ppdu_nss[SS_COUNT]; + uint32_t mpdu_cnt_fcs_ok; + uint32_t mpdu_cnt_fcs_err; + struct cdp_pkt_type su_ax_ppdu_cnt; + uint32_t ppdu_cnt[MAX_RECEPTION_TYPES]; + struct cdp_rx_mu rx_mu[RX_TYPE_MU_MAX]; uint32_t bw[MAX_BW]; uint32_t non_ampdu_cnt; uint32_t ampdu_cnt; diff --git a/dp/wifi3.0/dp_rx_mon_status.c b/dp/wifi3.0/dp_rx_mon_status.c index f8c6b2704f..e23f4694b4 100644 --- a/dp/wifi3.0/dp_rx_mon_status.c +++ b/dp/wifi3.0/dp_rx_mon_status.c @@ -116,7 +116,7 @@ dp_rx_inc_rusize_cnt(struct dp_pdev *pdev, uint32_t ru_size; bool is_data; - ru_size = rx_user_status->dl_ofdma_ru_size; + ru_size = rx_user_status->ofdma_ru_size; if (dp_is_subtype_data(rx_user_status->frame_control)) { DP_STATS_INC(pdev, @@ -169,19 +169,19 @@ dp_rx_populate_cdp_indication_ppdu_user(struct dp_pdev *pdev, ast_index = rx_user_status->ast_index; if (ast_index >= wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx)) { rx_stats_peruser->peer_id = HTT_INVALID_PEER; - return; + continue; } ast_entry = soc->ast_table[ast_index]; if (!ast_entry) { rx_stats_peruser->peer_id = HTT_INVALID_PEER; - return; + continue; } peer = ast_entry->peer; if (!peer || peer->peer_ids[0] == HTT_INVALID_PEER) { rx_stats_peruser->peer_id = HTT_INVALID_PEER; - return; + continue; } rx_stats_peruser->first_data_seq_ctrl = @@ -198,6 +198,12 @@ dp_rx_populate_cdp_indication_ppdu_user(struct dp_pdev *pdev, rx_user_status->udp_msdu_count; rx_stats_peruser->other_msdu_count = rx_user_status->other_msdu_count; + + rx_stats_peruser->num_msdu = + rx_stats_peruser->tcp_msdu_count + + rx_stats_peruser->udp_msdu_count + + rx_stats_peruser->other_msdu_count; + rx_stats_peruser->preamble_type = rx_user_status->preamble_type; rx_stats_peruser->mpdu_cnt_fcs_ok = @@ -214,10 +220,7 @@ dp_rx_populate_cdp_indication_ppdu_user(struct dp_pdev *pdev, rx_user_status->mpdu_err_byte_count; cdp_rx_ppdu->num_mpdu += rx_user_status->mpdu_cnt_fcs_ok; - cdp_rx_ppdu->num_msdu += - (rx_stats_peruser->tcp_msdu_count + - rx_stats_peruser->udp_msdu_count + - rx_stats_peruser->other_msdu_count); + cdp_rx_ppdu->num_msdu += rx_stats_peruser->num_msdu; rx_stats_peruser->retries = CDP_FC_IS_RETRY_SET(rx_stats_peruser->frame_control) ? rx_stats_peruser->mpdu_cnt_fcs_ok : 0; @@ -234,20 +237,21 @@ dp_rx_populate_cdp_indication_ppdu_user(struct dp_pdev *pdev, rx_stats_peruser->peer_id = peer->peer_ids[0]; cdp_rx_ppdu->vdev_id = peer->vdev->vdev_id; rx_stats_peruser->vdev_id = peer->vdev->vdev_id; - rx_stats_peruser->ofdma_info_valid = 0; + rx_stats_peruser->mu_ul_info_valid = 0; - if (cdp_rx_ppdu->u.ppdu_type == HAL_RX_TYPE_MU_OFDMA) { - if (rx_user_status->ofdma_info_valid) { + if (cdp_rx_ppdu->u.ppdu_type == HAL_RX_TYPE_MU_OFDMA || + cdp_rx_ppdu->u.ppdu_type == HAL_RX_TYPE_MU_MIMO) { + if (rx_user_status->mu_ul_info_valid) { rx_stats_peruser->nss = rx_user_status->nss; rx_stats_peruser->mcs = rx_user_status->mcs; - rx_stats_peruser->ofdma_info_valid = - rx_user_status->ofdma_info_valid; + rx_stats_peruser->mu_ul_info_valid = + rx_user_status->mu_ul_info_valid; rx_stats_peruser->ofdma_ru_start_index = - rx_user_status->dl_ofdma_ru_start_index; + rx_user_status->ofdma_ru_start_index; rx_stats_peruser->ofdma_ru_width = - rx_user_status->dl_ofdma_ru_width; + rx_user_status->ofdma_ru_width; rx_stats_peruser->user_index = i; - ru_size = rx_user_status->dl_ofdma_ru_size; + ru_size = rx_user_status->ofdma_ru_size; /* * max RU size will be equal to * HTT_UL_OFDMA_V0_RU_SIZE_RU_996x2 @@ -396,24 +400,28 @@ dp_rx_populate_cdp_indication_ppdu(struct dp_pdev *pdev, */ #ifdef FEATURE_PERPKT_INFO static inline void dp_rx_rate_stats_update(struct dp_peer *peer, - struct cdp_rx_indication_ppdu *ppdu) + struct cdp_rx_indication_ppdu *ppdu, + uint32_t user) { uint32_t ratekbps = 0; uint32_t ppdu_rx_rate = 0; uint32_t nss = 0; uint32_t rix; uint16_t ratecode; + struct cdp_rx_stats_ppdu_user *ppdu_user; if (!peer || !ppdu) return; - if (ppdu->u.nss == 0) + ppdu_user = &ppdu->user[user]; + + if (ppdu_user->nss == 0) nss = 0; else - nss = ppdu->u.nss - 1; + nss = ppdu_user->nss - 1; ratekbps = dp_getrateindex(ppdu->u.gi, - ppdu->u.mcs, + ppdu_user->mcs, nss, ppdu->u.preamble, ppdu->u.bw, @@ -435,123 +443,205 @@ static inline void dp_rx_rate_stats_update(struct dp_peer *peer, peer->vdev->stats.rx.last_rx_rate = ratekbps; } -static void dp_rx_stats_update(struct dp_pdev *pdev, struct dp_peer *peer, +static void dp_rx_stats_update(struct dp_pdev *pdev, struct cdp_rx_indication_ppdu *ppdu) { struct dp_soc *soc = NULL; - uint8_t mcs, preamble, ac = 0; + uint8_t mcs, preamble, ac = 0, nss, ppdu_type; uint16_t num_msdu; - bool is_invalid_peer = false; uint8_t pkt_bw_offset; - - mcs = ppdu->u.mcs; - preamble = ppdu->u.preamble; - num_msdu = ppdu->num_msdu; + struct dp_peer *peer; + struct cdp_rx_stats_ppdu_user *ppdu_user; + uint32_t i; + enum cdp_mu_packet_type mu_pkt_type; if (pdev) soc = pdev->soc; else return; - if (!peer) { - is_invalid_peer = true; - peer = pdev->invalid_peer; - } - if (!soc || soc->process_rx_status) return; - switch (ppdu->u.bw) { - case CMN_BW_20MHZ: - pkt_bw_offset = PKT_BW_GAIN_20MHZ; - break; - case CMN_BW_40MHZ: - pkt_bw_offset = PKT_BW_GAIN_40MHZ; - break; - case CMN_BW_80MHZ: - pkt_bw_offset = PKT_BW_GAIN_80MHZ; - break; - case CMN_BW_160MHZ: - pkt_bw_offset = PKT_BW_GAIN_160MHZ; - break; - default: - pkt_bw_offset = 0; - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - "Invalid BW index = %d", ppdu->u.bw); - } + preamble = ppdu->u.preamble; + ppdu_type = ppdu->u.ppdu_type; - DP_STATS_UPD(peer, rx.rssi, (ppdu->rssi + pkt_bw_offset)); + for (i = 0; i < ppdu->num_users; i++) { + ppdu_user = &ppdu->user[i]; + peer = dp_peer_find_by_id(soc, ppdu_user->peer_id); - if (peer->stats.rx.avg_rssi == INVALID_RSSI) - peer->stats.rx.avg_rssi = peer->stats.rx.rssi; - else - peer->stats.rx.avg_rssi = - DP_GET_AVG_RSSI(peer->stats.rx.avg_rssi, - peer->stats.rx.rssi); + if (!peer) + peer = pdev->invalid_peer; - if ((preamble == DOT11_A) || (preamble == DOT11_B)) - ppdu->u.nss = 1; + ppdu->cookie = (void *)peer->wlanstats_ctx; - if (ppdu->u.nss) - DP_STATS_INC(peer, rx.nss[ppdu->u.nss - 1], num_msdu); + if (ppdu_type == HAL_RX_TYPE_SU) { + mcs = ppdu->u.mcs; + nss = ppdu->u.nss; + } else { + mcs = ppdu_user->mcs; + nss = ppdu_user->nss; + } - DP_STATS_INC(peer, rx.sgi_count[ppdu->u.gi], num_msdu); - DP_STATS_INC(peer, rx.bw[ppdu->u.bw], num_msdu); - DP_STATS_INC(peer, rx.reception_type[ppdu->u.ppdu_type], num_msdu); - DP_STATS_INCC(peer, rx.ampdu_cnt, num_msdu, ppdu->is_ampdu); - DP_STATS_INCC(peer, rx.non_ampdu_cnt, num_msdu, !(ppdu->is_ampdu)); - DP_STATS_UPD(peer, rx.rx_rate, mcs); - DP_STATS_INCC(peer, + num_msdu = ppdu_user->num_msdu; + switch (ppdu->u.bw) { + case CMN_BW_20MHZ: + pkt_bw_offset = PKT_BW_GAIN_20MHZ; + break; + case CMN_BW_40MHZ: + pkt_bw_offset = PKT_BW_GAIN_40MHZ; + break; + case CMN_BW_80MHZ: + pkt_bw_offset = PKT_BW_GAIN_80MHZ; + break; + case CMN_BW_160MHZ: + pkt_bw_offset = PKT_BW_GAIN_160MHZ; + break; + default: + pkt_bw_offset = 0; + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "Invalid BW index = %d", ppdu->u.bw); + } + + DP_STATS_UPD(peer, rx.rssi, (ppdu->rssi + pkt_bw_offset)); + + if (peer->stats.rx.avg_rssi == INVALID_RSSI) + peer->stats.rx.avg_rssi = ppdu->rssi; + else + peer->stats.rx.avg_rssi = + DP_GET_AVG_RSSI(peer->stats.rx.avg_rssi, + ppdu->rssi); + + if ((preamble == DOT11_A) || (preamble == DOT11_B)) + nss = 1; + + if (ppdu_type == HAL_RX_TYPE_SU) { + if (nss) { + DP_STATS_INC(peer, rx.nss[nss - 1], num_msdu); + DP_STATS_INC(peer, rx.ppdu_nss[nss - 1], 1); + } + + DP_STATS_INC(peer, rx.mpdu_cnt_fcs_ok, + ppdu_user->mpdu_cnt_fcs_ok); + DP_STATS_INC(peer, rx.mpdu_cnt_fcs_err, + ppdu_user->mpdu_cnt_fcs_err); + } + + if (ppdu_type >= HAL_RX_TYPE_MU_MIMO && + ppdu_type <= HAL_RX_TYPE_MU_OFDMA) { + if (ppdu_type == HAL_RX_TYPE_MU_MIMO) + mu_pkt_type = RX_TYPE_MU_MIMO; + else + mu_pkt_type = RX_TYPE_MU_OFDMA; + + if (nss) { + DP_STATS_INC(peer, rx.nss[nss - 1], num_msdu); + DP_STATS_INC(peer, + rx.rx_mu[mu_pkt_type].ppdu_nss[nss - 1], + 1); + } + + DP_STATS_INC(peer, + rx.rx_mu[mu_pkt_type].mpdu_cnt_fcs_ok, + ppdu_user->mpdu_cnt_fcs_ok); + DP_STATS_INC(peer, + rx.rx_mu[mu_pkt_type].mpdu_cnt_fcs_err, + ppdu_user->mpdu_cnt_fcs_err); + } + + DP_STATS_INC(peer, rx.sgi_count[ppdu->u.gi], num_msdu); + DP_STATS_INC(peer, rx.bw[ppdu->u.bw], num_msdu); + DP_STATS_INC(peer, rx.reception_type[ppdu->u.ppdu_type], + num_msdu); + DP_STATS_INC(peer, rx.ppdu_cnt[ppdu->u.ppdu_type], 1); + DP_STATS_INCC(peer, rx.ampdu_cnt, num_msdu, + ppdu_user->is_ampdu); + DP_STATS_INCC(peer, rx.non_ampdu_cnt, num_msdu, + !(ppdu_user->is_ampdu)); + DP_STATS_UPD(peer, rx.rx_rate, mcs); + DP_STATS_INCC(peer, rx.pkt_type[preamble].mcs_count[MAX_MCS - 1], num_msdu, ((mcs >= MAX_MCS_11A) && (preamble == DOT11_A))); - DP_STATS_INCC(peer, + DP_STATS_INCC(peer, rx.pkt_type[preamble].mcs_count[mcs], num_msdu, ((mcs < MAX_MCS_11A) && (preamble == DOT11_A))); - DP_STATS_INCC(peer, + DP_STATS_INCC(peer, rx.pkt_type[preamble].mcs_count[MAX_MCS - 1], num_msdu, ((mcs >= MAX_MCS_11B) && (preamble == DOT11_B))); - DP_STATS_INCC(peer, + DP_STATS_INCC(peer, rx.pkt_type[preamble].mcs_count[mcs], num_msdu, ((mcs < MAX_MCS_11B) && (preamble == DOT11_B))); - DP_STATS_INCC(peer, + DP_STATS_INCC(peer, rx.pkt_type[preamble].mcs_count[MAX_MCS - 1], num_msdu, ((mcs >= MAX_MCS_11A) && (preamble == DOT11_N))); - DP_STATS_INCC(peer, + DP_STATS_INCC(peer, rx.pkt_type[preamble].mcs_count[mcs], num_msdu, ((mcs < MAX_MCS_11A) && (preamble == DOT11_N))); - DP_STATS_INCC(peer, + DP_STATS_INCC(peer, rx.pkt_type[preamble].mcs_count[MAX_MCS - 1], num_msdu, ((mcs >= MAX_MCS_11AC) && (preamble == DOT11_AC))); - DP_STATS_INCC(peer, + DP_STATS_INCC(peer, rx.pkt_type[preamble].mcs_count[mcs], num_msdu, ((mcs < MAX_MCS_11AC) && (preamble == DOT11_AC))); - DP_STATS_INCC(peer, + DP_STATS_INCC(peer, rx.pkt_type[preamble].mcs_count[MAX_MCS - 1], num_msdu, ((mcs >= (MAX_MCS - 1)) && (preamble == DOT11_AX))); - DP_STATS_INCC(peer, + DP_STATS_INCC(peer, rx.pkt_type[preamble].mcs_count[mcs], num_msdu, ((mcs < (MAX_MCS - 1)) && (preamble == DOT11_AX))); - /* - * If invalid TID, it could be a non-qos frame, hence do not update - * any AC counters - */ - ac = TID_TO_WME_AC(ppdu->tid); - if (ppdu->tid != HAL_TID_INVALID) - DP_STATS_INC(peer, rx.wme_ac_type[ac], num_msdu); - dp_peer_stats_notify(pdev, peer); - DP_STATS_UPD(peer, rx.last_rssi, ppdu->rssi); + DP_STATS_INCC(peer, + rx.su_ax_ppdu_cnt.mcs_count[MAX_MCS - 1], 1, + ((mcs >= (MAX_MCS - 1)) && (preamble == DOT11_AX) && + (ppdu_type == HAL_RX_TYPE_SU))); + DP_STATS_INCC(peer, + rx.su_ax_ppdu_cnt.mcs_count[mcs], 1, + ((mcs < (MAX_MCS - 1)) && (preamble == DOT11_AX) && + (ppdu_type == HAL_RX_TYPE_SU))); + DP_STATS_INCC(peer, + rx.rx_mu[RX_TYPE_MU_OFDMA].ppdu.mcs_count[MAX_MCS - 1], + 1, ((mcs >= (MAX_MCS - 1)) && + (preamble == DOT11_AX) && + (ppdu_type == HAL_RX_TYPE_MU_OFDMA))); + DP_STATS_INCC(peer, + rx.rx_mu[RX_TYPE_MU_OFDMA].ppdu.mcs_count[mcs], + 1, ((mcs < (MAX_MCS - 1)) && + (preamble == DOT11_AX) && + (ppdu_type == HAL_RX_TYPE_MU_OFDMA))); + DP_STATS_INCC(peer, + rx.rx_mu[RX_TYPE_MU_MIMO].ppdu.mcs_count[MAX_MCS - 1], + 1, ((mcs >= (MAX_MCS - 1)) && + (preamble == DOT11_AX) && + (ppdu_type == HAL_RX_TYPE_MU_MIMO))); + DP_STATS_INCC(peer, + rx.rx_mu[RX_TYPE_MU_MIMO].ppdu.mcs_count[mcs], + 1, ((mcs < (MAX_MCS - 1)) && + (preamble == DOT11_AX) && + (ppdu_type == HAL_RX_TYPE_MU_MIMO))); - if (is_invalid_peer) - return; + /* + * If invalid TID, it could be a non-qos frame, hence do not + * update any AC counters + */ + ac = TID_TO_WME_AC(ppdu_user->tid); - if (dp_is_subtype_data(ppdu->frame_ctrl)) - dp_rx_rate_stats_update(peer, ppdu); + if (ppdu->tid != HAL_TID_INVALID) + DP_STATS_INC(peer, rx.wme_ac_type[ac], num_msdu); + dp_peer_stats_notify(pdev, peer); + DP_STATS_UPD(peer, rx.last_rssi, ppdu->rssi); + + if (peer == pdev->invalid_peer) + continue; + + if (dp_is_subtype_data(ppdu->frame_ctrl)) + dp_rx_rate_stats_update(peer, ppdu, i); #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE - dp_wdi_event_handler(WDI_EVENT_UPDATE_DP_STATS, pdev->soc, - &peer->stats, ppdu->peer_id, - UPDATE_PEER_STATS, pdev->pdev_id); + dp_wdi_event_handler(WDI_EVENT_UPDATE_DP_STATS, pdev->soc, + &peer->stats, ppdu->peer_id, + UPDATE_PEER_STATS, pdev->pdev_id); #endif + dp_peer_unref_del_find_by_id(peer); + } } #endif @@ -811,7 +901,6 @@ dp_rx_handle_ppdu_stats(struct dp_soc *soc, struct dp_pdev *pdev, struct hal_rx_ppdu_info *ppdu_info) { qdf_nbuf_t ppdu_nbuf; - struct dp_peer *peer; struct cdp_rx_indication_ppdu *cdp_rx_ppdu; /* @@ -862,12 +951,8 @@ dp_rx_handle_ppdu_stats(struct dp_soc *soc, struct dp_pdev *pdev, qdf_nbuf_put_tail(ppdu_nbuf, sizeof(struct cdp_rx_indication_ppdu)); cdp_rx_ppdu = (struct cdp_rx_indication_ppdu *)ppdu_nbuf->data; - peer = dp_peer_find_by_id(soc, cdp_rx_ppdu->peer_id); - if (peer) { - cdp_rx_ppdu->cookie = (void *)peer->wlanstats_ctx; - dp_rx_stats_update(pdev, peer, cdp_rx_ppdu); - dp_peer_unref_del_find_by_id(peer); - } + dp_rx_stats_update(pdev, cdp_rx_ppdu); + if (cdp_rx_ppdu->peer_id != HTT_INVALID_PEER) { dp_wdi_event_handler(WDI_EVENT_RX_PPDU_DESC, soc, ppdu_nbuf, @@ -967,17 +1052,18 @@ dp_rx_ul_ofdma_ru_size_to_width( } static inline void -dp_rx_mon_handle_ofdma_info(struct hal_rx_ppdu_info *ppdu_info) +dp_rx_mon_handle_mu_ul_info(struct hal_rx_ppdu_info *ppdu_info) { struct mon_rx_user_status *mon_rx_user_status; uint32_t num_users; uint32_t i; - uint32_t ul_ofdma_user_v0_word0; - uint32_t ul_ofdma_user_v0_word1; + uint32_t mu_ul_user_v0_word0; + uint32_t mu_ul_user_v0_word1; uint32_t ru_width; uint32_t ru_size; - if (ppdu_info->rx_status.reception_type != HAL_RX_TYPE_MU_OFDMA) + if (!(ppdu_info->rx_status.reception_type == HAL_RX_TYPE_MU_OFDMA || + ppdu_info->rx_status.reception_type == HAL_RX_TYPE_MU_MIMO)) return; num_users = ppdu_info->com_info.num_users; @@ -985,39 +1071,39 @@ dp_rx_mon_handle_ofdma_info(struct hal_rx_ppdu_info *ppdu_info) num_users = HAL_MAX_UL_MU_USERS; for (i = 0; i < num_users; i++) { mon_rx_user_status = &ppdu_info->rx_user_status[i]; - ul_ofdma_user_v0_word0 = - mon_rx_user_status->ul_ofdma_user_v0_word0; - ul_ofdma_user_v0_word1 = - mon_rx_user_status->ul_ofdma_user_v0_word1; + mu_ul_user_v0_word0 = + mon_rx_user_status->mu_ul_user_v0_word0; + mu_ul_user_v0_word1 = + mon_rx_user_status->mu_ul_user_v0_word1; if (HTT_UL_OFDMA_USER_INFO_V0_W0_VALID_GET( - ul_ofdma_user_v0_word0) && + mu_ul_user_v0_word0) && !HTT_UL_OFDMA_USER_INFO_V0_W0_VER_GET( - ul_ofdma_user_v0_word0)) { + mu_ul_user_v0_word0)) { mon_rx_user_status->mcs = HTT_UL_OFDMA_USER_INFO_V0_W1_MCS_GET( - ul_ofdma_user_v0_word1); + mu_ul_user_v0_word1); mon_rx_user_status->nss = HTT_UL_OFDMA_USER_INFO_V0_W1_NSS_GET( - ul_ofdma_user_v0_word1) + 1; + mu_ul_user_v0_word1) + 1; - mon_rx_user_status->ofdma_info_valid = 1; - mon_rx_user_status->dl_ofdma_ru_start_index = + mon_rx_user_status->mu_ul_info_valid = 1; + mon_rx_user_status->ofdma_ru_start_index = HTT_UL_OFDMA_USER_INFO_V0_W1_RU_START_GET( - ul_ofdma_user_v0_word1); + mu_ul_user_v0_word1); ru_size = HTT_UL_OFDMA_USER_INFO_V0_W1_RU_SIZE_GET( - ul_ofdma_user_v0_word1); + mu_ul_user_v0_word1); dp_rx_ul_ofdma_ru_size_to_width(ru_size, &ru_width); - mon_rx_user_status->dl_ofdma_ru_width = ru_width; - mon_rx_user_status->dl_ofdma_ru_size = ru_size; + mon_rx_user_status->ofdma_ru_width = ru_width; + mon_rx_user_status->ofdma_ru_size = ru_size; } } } #else static inline void -dp_rx_mon_handle_ofdma_info(struct hal_rx_ppdu_info *ppdu_info) +dp_rx_mon_handle_mu_ul_info(struct hal_rx_ppdu_info *ppdu_info) { } #endif @@ -1132,7 +1218,7 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id, dp_rx_mon_deliver_non_std(soc, mac_id); } else if (tlv_status == HAL_TLV_STATUS_PPDU_DONE) { rx_mon_stats->status_ppdu_done++; - dp_rx_mon_handle_ofdma_info(ppdu_info); + dp_rx_mon_handle_mu_ul_info(ppdu_info); if (pdev->enhanced_stats_en || pdev->mcopy_mode || pdev->neighbour_peers_added) dp_rx_handle_ppdu_stats(soc, pdev, ppdu_info); diff --git a/dp/wifi3.0/dp_stats.c b/dp/wifi3.0/dp_stats.c index 65f2878948..7dda552c83 100644 --- a/dp/wifi3.0/dp_stats.c +++ b/dp/wifi3.0/dp_stats.c @@ -56,7 +56,7 @@ #define DP_NSS_LENGTH (6 * SS_COUNT) #define DP_MU_GROUP_LENGTH (6 * DP_MU_GROUP_SHOW) #define DP_MU_GROUP_SHOW 16 -#define DP_MAX_MCS_STRING_LEN 30 +#define DP_MAX_MCS_STRING_LEN 34 #define DP_RXDMA_ERR_LENGTH (6 * HAL_RXDMA_ERR_MAX) #define DP_REO_ERR_LENGTH (6 * HAL_REO_ERR_MAX) #define STATS_PROC_TIMEOUT (HZ / 1000) @@ -153,6 +153,61 @@ static const struct dp_rate_debug dp_rate_string[DOT11_MAX][MAX_MCS] = { } }; +static const struct dp_rate_debug dp_ppdu_rate_string[DOT11_MAX][MAX_MCS] = { + { + {"HE MCS 0 (BPSK 1/2) ", MCS_VALID}, + {"HE MCS 1 (QPSK 1/2) ", MCS_VALID}, + {"HE MCS 2 (QPSK 3/4) ", MCS_VALID}, + {"HE MCS 3 (16-QAM 1/2) ", MCS_VALID}, + {"HE MCS 4 (16-QAM 3/4) ", MCS_VALID}, + {"HE MCS 5 (64-QAM 2/3) ", MCS_VALID}, + {"HE MCS 6 (64-QAM 3/4) ", MCS_VALID}, + {"HE MCS 7 (64-QAM 5/6) ", MCS_VALID}, + {"HE MCS 8 (256-QAM 3/4) ", MCS_VALID}, + {"HE MCS 9 (256-QAM 5/6) ", MCS_VALID}, + {"HE MCS 10 (1024-QAM 3/4)", MCS_VALID}, + {"HE MCS 11 (1024-QAM 5/6)", MCS_VALID}, + {"INVALID ", MCS_VALID}, + } +}; + +static const struct dp_rate_debug dp_mu_rate_string[RX_TYPE_MU_MAX][MAX_MCS] = { + { + {"HE MU-MIMO MCS 0 (BPSK 1/2) ", MCS_VALID}, + {"HE MU-MIMO MCS 1 (QPSK 1/2) ", MCS_VALID}, + {"HE MU-MIMO MCS 2 (QPSK 3/4) ", MCS_VALID}, + {"HE MU-MIMO MCS 3 (16-QAM 1/2) ", MCS_VALID}, + {"HE MU-MIMO MCS 4 (16-QAM 3/4) ", MCS_VALID}, + {"HE MU-MIMO MCS 5 (64-QAM 2/3) ", MCS_VALID}, + {"HE MU-MIMO MCS 6 (64-QAM 3/4) ", MCS_VALID}, + {"HE MU-MIMO MCS 7 (64-QAM 5/6) ", MCS_VALID}, + {"HE MU-MIMO MCS 8 (256-QAM 3/4) ", MCS_VALID}, + {"HE MU-MIMO MCS 9 (256-QAM 5/6) ", MCS_VALID}, + {"HE MU-MIMO MCS 10 (1024-QAM 3/4)", MCS_VALID}, + {"HE MU-MIMO MCS 11 (1024-QAM 5/6)", MCS_VALID}, + {"INVALID ", MCS_VALID}, + }, + { + {"HE OFDMA MCS 0 (BPSK 1/2) ", MCS_VALID}, + {"HE OFDMA MCS 1 (QPSK 1/2) ", MCS_VALID}, + {"HE OFDMA MCS 2 (QPSK 3/4) ", MCS_VALID}, + {"HE OFDMA MCS 3 (16-QAM 1/2) ", MCS_VALID}, + {"HE OFDMA MCS 4 (16-QAM 3/4) ", MCS_VALID}, + {"HE OFDMA MCS 5 (64-QAM 2/3) ", MCS_VALID}, + {"HE OFDMA MCS 6 (64-QAM 3/4) ", MCS_VALID}, + {"HE OFDMA MCS 7 (64-QAM 5/6) ", MCS_VALID}, + {"HE OFDMA MCS 8 (256-QAM 3/4) ", MCS_VALID}, + {"HE OFDMA MCS 9 (256-QAM 5/6) ", MCS_VALID}, + {"HE OFDMA MCS 10 (1024-QAM 3/4)", MCS_VALID}, + {"HE OFDMA MCS 11 (1024-QAM 5/6)", MCS_VALID}, + {"INVALID ", MCS_VALID}, + }, +}; + +const char *mu_reception_mode[RX_TYPE_MU_MAX] = { + "MU MIMO", "MU OFDMA" +}; + #ifdef QCA_ENH_V3_STATS_SUPPORT const char *fw_to_hw_delay_bucket[CDP_DELAY_BUCKET_MAX + 1] = { "0 to 10 ms", "11 to 20 ms", @@ -4790,6 +4845,7 @@ dp_print_common_rates_info(struct cdp_pkt_type *pkt_type_array) { uint8_t mcs, pkt_type; + DP_PRINT_STATS("MSDU Count"); for (pkt_type = 0; pkt_type < DOT11_MAX; pkt_type++) { for (mcs = 0; mcs < MAX_MCS; mcs++) { if (!dp_rate_string[pkt_type][mcs].valid) @@ -4804,6 +4860,56 @@ dp_print_common_rates_info(struct cdp_pkt_type *pkt_type_array) } } +/** + * dp_print_common_ppdu_rates_info(): Print common rate for tx or rx + * @pkt_type_array: rate type array contains rate info + * + * Return:void + */ +static inline void +dp_print_common_ppdu_rates_info(struct cdp_pkt_type *pkt_type_array) +{ + uint8_t mcs; + + DP_PRINT_STATS("PPDU Count"); + for (mcs = 0; mcs < MAX_MCS; mcs++) { + if (!dp_ppdu_rate_string[0][mcs].valid) + continue; + + DP_PRINT_STATS(" %s = %d", + dp_ppdu_rate_string[0][mcs].mcs_type, + pkt_type_array->mcs_count[mcs]); + } + + DP_PRINT_STATS("\n"); +} + +/** + * dp_print_mu_ppdu_rates_info(): Print mu rate for tx or rx + * @rx_mu: rx MU stats array + * + * Return:void + */ +static inline void +dp_print_mu_ppdu_rates_info(struct cdp_rx_mu *rx_mu) +{ + uint8_t mcs, pkt_type; + + DP_PRINT_STATS("PPDU Count"); + for (pkt_type = 0; pkt_type < RX_TYPE_MU_MAX; pkt_type++) { + for (mcs = 0; mcs < MAX_MCS; mcs++) { + if (!dp_mu_rate_string[pkt_type][mcs].valid) + continue; + + DP_PRINT_STATS(" %s = %d", + dp_mu_rate_string[pkt_type][mcs].mcs_type, + rx_mu[pkt_type].ppdu.mcs_count[mcs]); + } + + DP_PRINT_STATS("\n"); + } +} + void dp_print_rx_rates(struct dp_vdev *vdev) { struct dp_pdev *pdev = (struct dp_pdev *)vdev->pdev; @@ -4881,6 +4987,26 @@ void dp_print_tx_rates(struct dp_vdev *vdev) pdev->stats.tx.non_amsdu_cnt); } +/** + * dp_print_nss(): Print nss count + * @nss: printable nss count array + * @pnss: nss count array + * @ss_count: number of nss + * + * Return:void + */ +static void dp_print_nss(char *nss, uint32_t *pnss, uint32_t ss_count) +{ + uint32_t index; + uint8_t i; + + index = 0; + for (i = 0; i < ss_count; i++) { + index += qdf_snprint(&nss[index], DP_NSS_LENGTH - index, + " %d", *(pnss + i)); + } +} + void dp_print_peer_stats(struct dp_peer *peer) { uint8_t i; @@ -4889,6 +5015,9 @@ void dp_print_peer_stats(struct dp_peer *peer) char nss[DP_NSS_LENGTH]; char mu_group_id[DP_MU_GROUP_LENGTH]; struct dp_pdev *pdev; + uint32_t *pnss; + enum cdp_mu_packet_type rx_mu_type; + struct cdp_rx_mu *rx_mu; pdev = peer->vdev->pdev; @@ -4972,11 +5101,9 @@ void dp_print_peer_stats(struct dp_peer *peer) peer->stats.tx.bw[0], peer->stats.tx.bw[1], peer->stats.tx.bw[2], peer->stats.tx.bw[3]); - index = 0; - for (i = 0; i < SS_COUNT; i++) { - index += qdf_snprint(&nss[index], DP_NSS_LENGTH - index, - " %d", peer->stats.tx.nss[i]); - } + pnss = &peer->stats.tx.nss[0]; + dp_print_nss(nss, pnss, SS_COUNT); + DP_PRINT_STATS("NSS(1-8) = %s", nss); DP_PRINT_STATS("Transmit Type :"); @@ -5080,21 +5207,53 @@ void dp_print_peer_stats(struct dp_peer *peer) DP_PRINT_STATS("BW Counts = 20MHZ %d 40MHZ %d 80MHZ %d 160MHZ %d", peer->stats.rx.bw[0], peer->stats.rx.bw[1], peer->stats.rx.bw[2], peer->stats.rx.bw[3]); - DP_PRINT_STATS("Reception Type = SU %d MU_MIMO %d MU_OFDMA %d MU_OFDMA_MIMO %d", + DP_PRINT_STATS("MSDU Reception Type"); + DP_PRINT_STATS("SU %d MU_MIMO %d MU_OFDMA %d MU_OFDMA_MIMO %d", peer->stats.rx.reception_type[0], peer->stats.rx.reception_type[1], peer->stats.rx.reception_type[2], peer->stats.rx.reception_type[3]); + DP_PRINT_STATS("PPDU Reception Type"); + DP_PRINT_STATS("SU %d MU_MIMO %d MU_OFDMA %d MU_OFDMA_MIMO %d", + peer->stats.rx.ppdu_cnt[0], + peer->stats.rx.ppdu_cnt[1], + peer->stats.rx.ppdu_cnt[2], + peer->stats.rx.ppdu_cnt[3]); dp_print_common_rates_info(peer->stats.rx.pkt_type); + dp_print_common_ppdu_rates_info(&peer->stats.rx.su_ax_ppdu_cnt); + dp_print_mu_ppdu_rates_info(&peer->stats.rx.rx_mu[0]); - index = 0; - for (i = 0; i < SS_COUNT; i++) { - index += qdf_snprint(&nss[index], DP_NSS_LENGTH - index, - " %d", peer->stats.rx.nss[i]); + pnss = &peer->stats.rx.nss[0]; + dp_print_nss(nss, pnss, SS_COUNT); + DP_PRINT_STATS("MSDU Count"); + DP_PRINT_STATS(" NSS(1-8) = %s", nss); + + DP_PRINT_STATS("reception mode SU"); + pnss = &peer->stats.rx.ppdu_nss[0]; + dp_print_nss(nss, pnss, SS_COUNT); + + DP_PRINT_STATS(" PPDU Count"); + DP_PRINT_STATS(" NSS(1-8) = %s", nss); + + DP_PRINT_STATS(" MPDU OK = %d, MPDU Fail = %d", + peer->stats.rx.mpdu_cnt_fcs_ok, + peer->stats.rx.mpdu_cnt_fcs_err); + + for (rx_mu_type = 0; rx_mu_type < RX_TYPE_MU_MAX; rx_mu_type++) { + DP_PRINT_STATS("reception mode %s", + mu_reception_mode[rx_mu_type]); + rx_mu = &peer->stats.rx.rx_mu[rx_mu_type]; + + pnss = &rx_mu->ppdu_nss[0]; + dp_print_nss(nss, pnss, SS_COUNT); + DP_PRINT_STATS(" PPDU Count"); + DP_PRINT_STATS(" NSS(1-8) = %s", nss); + + DP_PRINT_STATS(" MPDU OK = %d, MPDU Fail = %d", + rx_mu->mpdu_cnt_fcs_ok, + rx_mu->mpdu_cnt_fcs_err); } - DP_PRINT_STATS("NSS(1-8) = %s", - nss); DP_PRINT_STATS("Aggregation:"); DP_PRINT_STATS(" Msdu's Part of Ampdu = %d", diff --git a/hal/wifi3.0/hal_generic_api.h b/hal/wifi3.0/hal_generic_api.h index ab8820097c..ef4ccc3ed1 100644 --- a/hal/wifi3.0/hal_generic_api.h +++ b/hal/wifi3.0/hal_generic_api.h @@ -219,15 +219,15 @@ hal_rx_handle_other_tlvs(uint32_t tlv_tag, void *rx_tlv, defined(RX_PPDU_END_USER_STATS_22_SW_RESPONSE_REFERENCE_PTR_EXT_OFFSET) static inline void -hal_rx_handle_ofdma_info( +hal_rx_handle_mu_ul_info( void *rx_tlv, struct mon_rx_user_status *mon_rx_user_status) { - mon_rx_user_status->ul_ofdma_user_v0_word0 = + mon_rx_user_status->mu_ul_user_v0_word0 = HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_11, SW_RESPONSE_REFERENCE_PTR); - mon_rx_user_status->ul_ofdma_user_v0_word1 = + mon_rx_user_status->mu_ul_user_v0_word1 = HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_22, SW_RESPONSE_REFERENCE_PTR_EXT); } @@ -251,7 +251,7 @@ hal_rx_populate_byte_count(void *rx_tlv, void *ppduinfo, } #else static inline void -hal_rx_handle_ofdma_info(void *rx_tlv, +hal_rx_handle_mu_ul_info(void *rx_tlv, struct mon_rx_user_status *mon_rx_user_status) { } @@ -546,7 +546,7 @@ hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo, mon_rx_user_status = &ppdu_info->rx_user_status[user_id]; - hal_rx_handle_ofdma_info(rx_tlv, mon_rx_user_status); + hal_rx_handle_mu_ul_info(rx_tlv, mon_rx_user_status); ppdu_info->com_info.num_users++; diff --git a/qdf/inc/qdf_nbuf.h b/qdf/inc/qdf_nbuf.h index 2318d37bf8..6661bcc781 100644 --- a/qdf/inc/qdf_nbuf.h +++ b/qdf/inc/qdf_nbuf.h @@ -328,9 +328,12 @@ struct mon_rx_status { * extracted from hardware TLV. * @mcs: MCS index of Rx frame * @nss: Number of spatial streams - * @ofdma_info_valid: OFDMA info below is valid - * @dl_ofdma_ru_start_index: OFDMA RU start index - * @dl_ofdma_ru_width: OFDMA total RU width + * @mu_ul_info_valid: MU UL info below is valid + * @ofdma_ru_start_index: OFDMA RU start index + * @ofdma_ru_width: OFDMA total RU width + * @ofdma_ru_size: OFDMA RU size index + * @mu_ul_user_v0_word0: MU UL user info word 0 + * @mu_ul_user_v0_word1: MU UL user info word 1 * @ast_index: AST table hash index * @tid: QoS traffic tid number * @tcp_msdu_count: tcp protocol msdu count @@ -355,12 +358,12 @@ struct mon_rx_status { struct mon_rx_user_status { uint32_t mcs:4, nss:3, - ofdma_info_valid:1, - dl_ofdma_ru_start_index:7, - dl_ofdma_ru_width:7, - dl_ofdma_ru_size:8; - uint32_t ul_ofdma_user_v0_word0; - uint32_t ul_ofdma_user_v0_word1; + mu_ul_info_valid:1, + ofdma_ru_start_index:7, + ofdma_ru_width:7, + ofdma_ru_size:8; + uint32_t mu_ul_user_v0_word0; + uint32_t mu_ul_user_v0_word1; uint32_t ast_index; uint32_t tid; uint16_t tcp_msdu_count;