diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h index 53c2e3b9e2..939a6c3746 100644 --- a/dp/inc/cdp_txrx_cmn_struct.h +++ b/dp/inc/cdp_txrx_cmn_struct.h @@ -2041,6 +2041,7 @@ struct cdp_delayed_tx_completion_ppdu_user { * @punc_mode: puncutured mode to indicate punctured bw * @punc_pattern_bitmap: bitmap indicating punctured pattern * @mprot_type: medium protection type + * @msduq_bitmap: msduq bitmap * @rts_success: rts success * @rts_failure: rts failure */ @@ -2147,6 +2148,7 @@ struct cdp_tx_completion_ppdu_user { uint32_t mpdu_bytes; uint8_t punc_mode; uint16_t punc_pattern_bitmap; + uint32_t msduq_bitmap; uint8_t mprot_type:3, rts_success:1, rts_failure:1; @@ -2313,6 +2315,9 @@ struct cdp_tx_mgmt_comp_info { * @sched_cmdid: schedule command id * @phy_ppdu_tx_time_us: Phy per PPDU TX duration * @ppdu_bytes: accumulated bytes per ppdu for mem limit feature + * @htt_seq_type: Seq type + * @txmode_type: tx mode type UL/DL + * @txmode: tx mode * @user: per-User stats (array of per-user structures) */ struct cdp_tx_completion_ppdu { @@ -2358,6 +2363,9 @@ struct cdp_tx_completion_ppdu { uint16_t sched_cmdid; uint16_t phy_ppdu_tx_time_us; uint32_t ppdu_bytes; + uint8_t htt_seq_type; + uint8_t txmode_type; + uint8_t txmode; struct cdp_tx_completion_ppdu_user user[]; }; diff --git a/dp/inc/cdp_txrx_stats_struct.h b/dp/inc/cdp_txrx_stats_struct.h index 1203ff5305..2bd4c94f03 100644 --- a/dp/inc/cdp_txrx_stats_struct.h +++ b/dp/inc/cdp_txrx_stats_struct.h @@ -326,6 +326,65 @@ enum cdp_tx_transmit_type { MU_MIMO_OFDMA, }; +/* + * cdp_tx_mode_type: Uplink transmit mode type + * TX_MODE_TYPE_DL: DL TX mode + * TX_MODE_TYPE_UL: UL TX mode + * TX_MODE_TYPE_UNKNOWN: UL TX mode unknown + */ +enum cdp_tx_mode_type { + TX_MODE_TYPE_DL = 0, + TX_MODE_TYPE_UL, + TX_MODE_TYPE_UNKNOWN, +}; + +/* + * cdp_tx_mode_dl: Downlink transmit mode index + * TX_MODE_DL_SU_DATA: SU Transmit type index + * TX_MODE_DL_OFDMA_DATA: OFDMA Transmit type index + * TX_MODE_DL_MUMIMO_DATA: MIMO Transmit type index + */ +enum cdp_tx_mode_dl { + TX_MODE_DL_SU_DATA = 0, + TX_MODE_DL_OFDMA_DATA, + TX_MODE_DL_MUMIMO_DATA, + TX_MODE_DL_MAX, +}; + +/* + * cdp_tx_mode_ul: Uplink transmit mode index + * TX_MODE_UL_OFDMA_BASIC_TRIGGER_DATA: UL ofdma trigger index + * TX_MODE_UL_MUMIMO_BASIC_TRIGGER_DATA: UL mimo trigger index + * TX_MODE_UL_OFDMA_MU_BAR_TRIGGER: UL ofdma MU-BAR trigger index + */ +enum cdp_tx_mode_ul { + TX_MODE_UL_OFDMA_BASIC_TRIGGER_DATA = 0, + TX_MODE_UL_MUMIMO_BASIC_TRIGGER_DATA, + TX_MODE_UL_OFDMA_MU_BAR_TRIGGER, + TX_MODE_UL_MAX, +}; + +/* + * cdp_msduq_index: TX msdu queue + * MSDUQ_INDEX_DEFAULT: TCP/UDP msduq index + * MSDUQ_INDEX_CUSTOM_PRIO_0: custom priority msduq index + * MSDUQ_INDEX_CUSTOM_PRIO_1: custom priority msduq index + * MSDUQ_INDEX_CUSTOM_EXT_PRIO_0: custom ext priority msduq index + * MSDUQ_INDEX_CUSTOM_EXT_PRIO_1: custom ext priority msduq index + * MSDUQ_INDEX_CUSTOM_EXT_PRIO_2: custom ext priority msduq index + * MSDUQ_INDEX_CUSTOM_EXT_PRIO_3: custom ext priority msduq index + */ +enum cdp_msduq_index { + MSDUQ_INDEX_DEFAULT = 0, + MSDUQ_INDEX_CUSTOM_PRIO_0, + MSDUQ_INDEX_CUSTOM_PRIO_1, + MSDUQ_INDEX_CUSTOM_EXT_PRIO_0, + MSDUQ_INDEX_CUSTOM_EXT_PRIO_1, + MSDUQ_INDEX_CUSTOM_EXT_PRIO_2, + MSDUQ_INDEX_CUSTOM_EXT_PRIO_3, + MSDUQ_INDEX_MAX, +}; + /* * cdp_ru_index: Different RU index * @@ -2854,6 +2913,30 @@ struct cdp_peer_telemetry_stats { uint16_t rx_airtime_consumption[WME_AC_MAX]; uint8_t snr; }; + +/** + * struct cdp_peer_tx_dl_deter- Structure to hold peer DL deterministic stats + * @avg_rate: Average TX rate + * @mode_cnt: TX mode count + */ +struct cdp_peer_tx_dl_deter { + uint64_t avg_rate; + uint32_t mode_cnt; +}; + +/** + * struct cdp_peer_tx_ul_deter- Structure to hold peer UL deterministic stats + * @avg_rate: Average TX rate + * @mode_cnt: TX mode count + * @trigger_success: Trigger frame received success + * @trigger_fail: Trigger frame received fail + */ +struct cdp_peer_tx_ul_deter { + uint64_t avg_rate; + uint32_t mode_cnt; + uint32_t trigger_success; + uint32_t trigger_fail; +}; #endif /* struct cdp_pdev_stats - pdev stats diff --git a/dp/wifi3.0/monitor/dp_mon.c b/dp/wifi3.0/monitor/dp_mon.c index 8c1406de1f..0b008d4a3d 100644 --- a/dp/wifi3.0/monitor/dp_mon.c +++ b/dp/wifi3.0/monitor/dp_mon.c @@ -2996,7 +2996,191 @@ dp_pdev_telemetry_stats_update( DP_STATS_INC(pdev, telemetry_stats.tx_mpdu_total[ac], mpdu_tried); } + +/* + * dp_ppdu_desc_get_txmode() - Get TX mode + * @ppdu: PPDU Descriptor + * + * Return: None + */ +static inline +void dp_ppdu_desc_get_txmode(struct cdp_tx_completion_ppdu *ppdu) +{ + uint16_t frame_type = ppdu->htt_frame_type; + + if (ppdu->frame_type != CDP_PPDU_FTYPE_DATA) + return; + + ppdu->txmode_type = TX_MODE_TYPE_UNKNOWN; + + if (frame_type == HTT_STATS_FTYPE_SGEN_MU_BAR || + frame_type == HTT_STATS_FTYPE_SGEN_BE_MU_BAR) { + ppdu->txmode = TX_MODE_UL_OFDMA_MU_BAR_TRIGGER; + ppdu->txmode_type = TX_MODE_TYPE_UL; + + return; + } + + switch (ppdu->htt_seq_type) { + case HTT_SEQTYPE_SU: + if (frame_type == HTT_STATS_FTYPE_TIDQ_DATA_SU) { + ppdu->txmode = TX_MODE_DL_SU_DATA; + ppdu->txmode_type = TX_MODE_TYPE_DL; + } + break; + case HTT_SEQTYPE_MU_OFDMA: + case HTT_SEQTYPE_BE_MU_OFDMA: + if (frame_type == HTT_STATS_FTYPE_TIDQ_DATA_MU) { + ppdu->txmode = TX_MODE_DL_OFDMA_DATA; + ppdu->txmode_type = TX_MODE_TYPE_DL; + } + break; + case HTT_SEQTYPE_AC_MU_MIMO: + case HTT_SEQTYPE_AX_MU_MIMO: + case HTT_SEQTYPE_BE_MU_MIMO: + if (frame_type == HTT_STATS_FTYPE_TIDQ_DATA_MU) { + ppdu->txmode = TX_MODE_DL_MUMIMO_DATA; + ppdu->txmode_type = TX_MODE_TYPE_DL; + } + break; + case HTT_SEQTYPE_UL_MU_OFDMA_TRIG: + case HTT_SEQTYPE_BE_UL_MU_OFDMA_TRIG: + if (frame_type == HTT_STATS_FTYPE_SGEN_MU_TRIG || + frame_type == HTT_STATS_FTYPE_SGEN_BE_MU_TRIG) { + ppdu->txmode = TX_MODE_UL_OFDMA_BASIC_TRIGGER_DATA; + ppdu->txmode_type = TX_MODE_TYPE_UL; + } + break; + case HTT_SEQTYPE_UL_MU_MIMO_TRIG: + case HTT_SEQTYPE_BE_UL_MU_MIMO_TRIG: + if (frame_type == HTT_STATS_FTYPE_SGEN_MU_TRIG || + frame_type == HTT_STATS_FTYPE_SGEN_BE_MU_TRIG) { + ppdu->txmode = TX_MODE_UL_MUMIMO_BASIC_TRIGGER_DATA; + ppdu->txmode_type = TX_MODE_TYPE_UL; + } + break; + default: + ppdu->txmode_type = TX_MODE_TYPE_UNKNOWN; + break; + } +} + +/* + * dp_ppdu_desc_get_msduq() - Get msduq index from bitmap + * @ppdu: PPDU Descriptor + * @msduq_index: MSDUQ index + * + * Return: None + */ +static inline void +dp_ppdu_desc_get_msduq(uint32_t msduq_bitmap, uint32_t *msduq_index) +{ + if ((msduq_bitmap & BIT(HTT_MSDUQ_INDEX_NON_UDP)) || + (msduq_bitmap & BIT(HTT_MSDUQ_INDEX_UDP))) { + *msduq_index = MSDUQ_INDEX_DEFAULT; + } else if (msduq_bitmap & BIT(HTT_MSDUQ_INDEX_CUSTOM_PRIO_0)) { + *msduq_index = MSDUQ_INDEX_CUSTOM_PRIO_0; + } else if (msduq_bitmap & BIT(HTT_MSDUQ_INDEX_CUSTOM_PRIO_1)) { + *msduq_index = MSDUQ_INDEX_CUSTOM_PRIO_1; + } else if (msduq_bitmap & BIT(HTT_MSDUQ_INDEX_CUSTOM_EXT_PRIO_0)) { + *msduq_index = MSDUQ_INDEX_CUSTOM_EXT_PRIO_0; + } else if (msduq_bitmap & BIT(HTT_MSDUQ_INDEX_CUSTOM_EXT_PRIO_1)) { + *msduq_index = MSDUQ_INDEX_CUSTOM_EXT_PRIO_1; + } else if (msduq_bitmap & BIT(HTT_MSDUQ_INDEX_CUSTOM_EXT_PRIO_2)) { + *msduq_index = MSDUQ_INDEX_CUSTOM_EXT_PRIO_2; + } else if (msduq_bitmap & BIT(HTT_MSDUQ_INDEX_CUSTOM_EXT_PRIO_3)) { + *msduq_index = MSDUQ_INDEX_CUSTOM_EXT_PRIO_3; + } else { + *msduq_index = MSDUQ_INDEX_MAX; + } +} + +/* + * dp_ppdu_desc_user_deter_stats_update() - Update per-peer deterministic stats + * @pdev: Datapath pdev handle + * @peer: Datapath peer handle + * @ppdu_desc: PPDU Descriptor + * @user: PPDU Descriptor per user + * + * Return: None + */ +static void +dp_ppdu_desc_user_deter_stats_update(struct dp_pdev *pdev, + struct dp_peer *peer, + struct cdp_tx_completion_ppdu *ppdu_desc, + struct cdp_tx_completion_ppdu_user *user) +{ + struct dp_mon_peer *mon_peer = NULL; + uint32_t msduq; + uint8_t txmode; + uint8_t tid; + + if (!pdev || !ppdu_desc || !user || !peer) + return; + + if (ppdu_desc->frame_type != CDP_PPDU_FTYPE_DATA) + return; + + if (user->tid >= CDP_DATA_TID_MAX) + return; + + mon_peer = peer->monitor_peer; + if (qdf_unlikely(!mon_peer)) + return; + + if (ppdu_desc->txmode_type == TX_MODE_TYPE_UNKNOWN) + return; + + txmode = ppdu_desc->txmode; + tid = user->tid; + if (ppdu_desc->txmode_type == TX_MODE_TYPE_DL) { + dp_ppdu_desc_get_msduq(user->msduq_bitmap, &msduq); + if (msduq == MSDUQ_INDEX_MAX) + return; + + DP_STATS_INC(mon_peer, + deter_stats[tid].dl_det[msduq][txmode].mode_cnt, + 1); + DP_STATS_UPD(mon_peer, + deter_stats[tid].dl_det[msduq][txmode].avg_rate, + mon_peer->stats.tx.avg_tx_rate); + } else { + DP_STATS_INC(mon_peer, + deter_stats[tid].ul_det[txmode].mode_cnt, + 1); + DP_STATS_UPD(mon_peer, + deter_stats[tid].ul_det[txmode].avg_rate, + mon_peer->stats.tx.avg_tx_rate); + if (!user->completion_status) { + DP_STATS_INC(mon_peer, + deter_stats[tid].ul_det[txmode].trigger_success, + 1); + } else { + DP_STATS_INC(mon_peer, + deter_stats[tid].ul_det[txmode].trigger_fail, + 1); + } + } +} #else +static inline +void dp_ppdu_desc_get_txmode(struct cdp_tx_completion_ppdu *ppdu) +{ +} + +static inline void +dp_ppdu_desc_get_msduq(uint32_t msduq_bitmap, uint32_t *msduq_index) +{ +} + +static void +dp_ppdu_desc_user_deter_stats_update(struct dp_pdev *pdev, + struct dp_peer *peer, + struct cdp_tx_completion_ppdu *ppdu_desc, + struct cdp_tx_completion_ppdu_user *user) +{ +} + static inline void dp_pdev_telemetry_stats_update( struct dp_pdev *pdev, @@ -3008,15 +3192,15 @@ dp_pdev_telemetry_stats_update( * dp_tx_stats_update() - Update per-peer statistics * @pdev: Datapath pdev handle * @peer: Datapath peer handle - * @ppdu: PPDU Descriptor - * @ack_rssi: RSSI of last ack received + * @ppdu: PPDU Descriptor per user + * @ppdu_desc: PPDU Descriptor * * Return: None */ static void dp_tx_stats_update(struct dp_pdev *pdev, struct dp_peer *peer, struct cdp_tx_completion_ppdu_user *ppdu, - uint32_t ack_rssi) + struct cdp_tx_completion_ppdu *ppdu_desc) { uint8_t preamble, mcs; uint16_t num_msdu; @@ -3124,7 +3308,7 @@ dp_tx_stats_update(struct dp_pdev *pdev, struct dp_peer *peer, DP_STATS_INCC(mon_peer, tx.stbc, num_msdu, ppdu->stbc); DP_STATS_INCC(mon_peer, tx.ldpc, num_msdu, ppdu->ldpc); if (!(ppdu->is_mcast) && ppdu->ack_rssi_valid) - DP_STATS_UPD(mon_peer, tx.last_ack_rssi, ack_rssi); + DP_STATS_UPD(mon_peer, tx.last_ack_rssi, ppdu_desc->ack_rssi); if (!ppdu->is_mcast) { DP_STATS_INC(mon_peer, tx.tx_ucast_success.num, num_msdu); @@ -3176,6 +3360,9 @@ dp_tx_stats_update(struct dp_pdev *pdev, struct dp_peer *peer, dp_tx_rate_stats_update(peer, ppdu); dp_pdev_telemetry_stats_update(pdev, ppdu); + dp_ppdu_desc_user_deter_stats_update(pdev, peer, ppdu_desc, + ppdu); + dp_peer_stats_notify(pdev, peer); ratekbps = mon_peer->stats.tx.tx_rate; @@ -3263,6 +3450,9 @@ dp_process_ppdu_stats_common_tlv(struct dp_pdev *pdev, frame_type = HTT_PPDU_STATS_COMMON_TLV_FRM_TYPE_GET(*tag_buf); ppdu_desc->htt_frame_type = frame_type; + ppdu_desc->htt_seq_type = + HTT_PPDU_STATS_COMMON_TLV_PPDU_SEQ_TYPE_GET(*tag_buf); + frame_ctrl = ppdu_desc->frame_ctrl; ppdu_desc->bar_ppdu_id = ppdu_info->ppdu_id; @@ -3465,6 +3655,9 @@ static void dp_process_ppdu_stats_user_common_tlv( peer->mac_addr.raw, QDF_MAC_ADDR_SIZE); dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS); } + + tag_buf += 10; + ppdu_user_desc->msduq_bitmap = *tag_buf; } /** @@ -4526,6 +4719,8 @@ dp_ppdu_desc_user_stats_update(struct dp_pdev *pdev, } qdf_assert_always(ppdu_desc->num_users <= ppdu_desc->max_users); + dp_ppdu_desc_get_txmode(ppdu_desc); + for (i = 0; i < num_users; i++) { ppdu_desc->num_mpdu += ppdu_desc->user[i].num_mpdu; ppdu_desc->num_msdu += ppdu_desc->user[i].num_msdu; @@ -4582,7 +4777,7 @@ dp_ppdu_desc_user_stats_update(struct dp_pdev *pdev, (ppdu_desc->frame_type != CDP_PPDU_FTYPE_CTRL)) { dp_tx_stats_update(pdev, peer, &ppdu_desc->user[i], - ppdu_desc->ack_rssi); + ppdu_desc); } dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS); diff --git a/dp/wifi3.0/monitor/dp_mon.h b/dp/wifi3.0/monitor/dp_mon.h index f13ec2f04f..d40af8202b 100644 --- a/dp/wifi3.0/monitor/dp_mon.h +++ b/dp/wifi3.0/monitor/dp_mon.h @@ -911,6 +911,16 @@ struct dp_mon_peer_airtime_stats { struct dp_mon_peer_airtime_consumption rx_airtime_consumption[WME_AC_MAX]; uint64_t last_update_time; }; + +/** + * struct dp_mon_peer_deterministic - Monitor peer deterministic stats + * @dl_det: Downlink deterministic stats + * @ul_det: Uplink deterministic stats + */ +struct dp_mon_peer_deterministic { + struct cdp_peer_tx_dl_deter dl_det[MSDUQ_INDEX_MAX][TX_MODE_DL_MAX]; + struct cdp_peer_tx_ul_deter ul_det[TX_MODE_UL_MAX]; +}; #endif /** @@ -918,6 +928,7 @@ struct dp_mon_peer_airtime_stats { * @tx: tx stats * @rx: rx stats * @airtime_stats: mon peer airtime stats + * @deter_stats: Deterministic stats */ struct dp_mon_peer_stats { #ifdef QCA_ENHANCED_STATS_SUPPORT @@ -925,6 +936,7 @@ struct dp_mon_peer_stats { dp_mon_peer_rx_stats rx; #ifdef WLAN_TELEMETRY_STATS_SUPPORT struct dp_mon_peer_airtime_stats airtime_stats; + struct dp_mon_peer_deterministic deter_stats[CDP_DATA_TID_MAX]; #endif #endif };