diff --git a/dp/cmn_dp_api/dp_ratetable.h b/dp/cmn_dp_api/dp_ratetable.h index 8fd5fe947b..b47306c3c9 100644 --- a/dp/cmn_dp_api/dp_ratetable.h +++ b/dp/cmn_dp_api/dp_ratetable.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -30,6 +31,9 @@ enum CMN_BW_TYPES { CMN_BW_80MHZ, CMN_BW_160MHZ, CMN_BW_80_80MHZ, +#ifdef WLAN_FEATURE_11BE + CMN_BW_320MHZ, +#endif CMN_BW_CNT, CMN_BW_IDLE = 0xFF, /*default BW state */ }; diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h index 8e8bf64948..889b6c8f7a 100644 --- a/dp/inc/cdp_txrx_cmn_struct.h +++ b/dp/inc/cdp_txrx_cmn_struct.h @@ -2248,6 +2248,7 @@ struct cdp_tx_completion_msdu { * @mpdu_fcs_ok_bitmap - MPDU with fcs ok bitmap * @retries - number of retries * @rx_ratekpbs - rx rate in kbps + * @mpdu_retries - retries of mpdu in rx */ struct cdp_rx_stats_ppdu_user { uint16_t peer_id; @@ -2285,6 +2286,7 @@ struct cdp_rx_stats_ppdu_user { uint32_t mpdu_err_byte_count; uint32_t retries; uint32_t rx_ratekbps; + uint32_t mpdu_retries; }; /** @@ -2334,6 +2336,7 @@ struct cdp_rx_stats_ppdu_user { * @user: per user stats in MU-user case * @nf: noise floor * @per_chain_rssi: rssi per antenna + * @punc_bw: puncered bw */ struct cdp_rx_indication_ppdu { uint32_t ppdu_id; @@ -2394,6 +2397,7 @@ struct cdp_rx_indication_ppdu { #if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) struct cdp_rx_ppdu_cfr_info cfr_info; #endif + uint8_t punc_bw; }; /** diff --git a/dp/inc/cdp_txrx_stats_struct.h b/dp/inc/cdp_txrx_stats_struct.h index 3135247a41..93fba5a059 100644 --- a/dp/inc/cdp_txrx_stats_struct.h +++ b/dp/inc/cdp_txrx_stats_struct.h @@ -1424,6 +1424,9 @@ struct cdp_tx_stats { * HE * @preamble_info: preamble * @to_stack_twt: Total packets sent up the stack in TWT session + * @mpdu_retry_cnt: retries of mpdu in rx + * @su_be_ppdu_cnt: SU Rx packet count for BE + * @rx_mu_be: MU rx packet count for BE */ struct cdp_rx_stats { struct cdp_pkt_info to_stack; @@ -1505,6 +1508,11 @@ struct cdp_rx_stats { gi_info:4, preamble_info:4; struct cdp_pkt_info to_stack_twt; + uint32_t mpdu_retry_cnt; +#ifdef WLAN_FEATURE_11BE + struct cdp_pkt_type su_be_ppdu_cnt; + struct cdp_pkt_type rx_mu_be[TXRX_TYPE_MU_MAX]; +#endif }; /* struct cdp_tx_ingress_stats - Tx ingress Stats diff --git a/dp/wifi3.0/monitor/1.0/dp_mon_1.0.c b/dp/wifi3.0/monitor/1.0/dp_mon_1.0.c index 78d6ce7b97..9f9e8f0ebd 100644 --- a/dp/wifi3.0/monitor/1.0/dp_mon_1.0.c +++ b/dp/wifi3.0/monitor/1.0/dp_mon_1.0.c @@ -53,6 +53,15 @@ extern enum timer_yield_status dp_should_timer_irq_yield(struct dp_soc *soc, uint32_t work_done, uint64_t start_time); +#ifdef QCA_ENHANCED_STATS_SUPPORT +void +dp_mon_populate_ppdu_info_1_0(struct hal_rx_ppdu_info *hal_ppdu_info, + struct cdp_rx_indication_ppdu *ppdu) +{ + ppdu->punc_bw = 0; +} +#endif + #ifdef QCA_SUPPORT_FULL_MON static QDF_STATUS dp_config_full_mon_mode(struct cdp_soc_t *soc_handle, @@ -945,6 +954,11 @@ dp_mon_register_feature_ops_1_0(struct dp_soc *soc) dp_vdev_set_monitor_mode_buf_rings; mon_ops->mon_vdev_set_monitor_mode_rings = dp_vdev_set_monitor_mode_rings; +#ifdef QCA_ENHANCED_STATS_SUPPORT + mon_ops->mon_rx_stats_update = NULL; + mon_ops->mon_rx_populate_ppdu_usr_info = NULL; + mon_ops->mon_rx_populate_ppdu_info = dp_mon_populate_ppdu_info_1_0; +#endif } struct dp_mon_ops monitor_ops_1_0 = { diff --git a/dp/wifi3.0/monitor/2.0/dp_mon_2.0.c b/dp/wifi3.0/monitor/2.0/dp_mon_2.0.c index ef6adb8e2e..281e4c1f1a 100644 --- a/dp/wifi3.0/monitor/2.0/dp_mon_2.0.c +++ b/dp/wifi3.0/monitor/2.0/dp_mon_2.0.c @@ -926,6 +926,12 @@ dp_mon_register_feature_ops_2_0(struct dp_soc *soc) dp_vdev_set_monitor_mode_buf_rings_2_0; mon_ops->mon_vdev_set_monitor_mode_rings = dp_vdev_set_monitor_mode_rings_2_0; +#ifdef QCA_ENHANCED_STATS_SUPPORT + mon_ops->mon_rx_stats_update = dp_mon_rx_stats_update_2_0; + mon_ops->mon_rx_populate_ppdu_usr_info = + dp_mon_populate_ppdu_usr_info_2_0; + mon_ops->mon_rx_populate_ppdu_info = dp_mon_populate_ppdu_info_2_0; +#endif } struct dp_mon_ops monitor_ops_2_0 = { diff --git a/dp/wifi3.0/monitor/2.0/dp_rx_mon_2.0.c b/dp/wifi3.0/monitor/2.0/dp_rx_mon_2.0.c index 284efeea58..c3900d0337 100644 --- a/dp/wifi3.0/monitor/2.0/dp_rx_mon_2.0.c +++ b/dp/wifi3.0/monitor/2.0/dp_rx_mon_2.0.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -198,3 +199,78 @@ dp_rx_mon_buffers_alloc(struct dp_soc *soc) mon_soc->rx_mon_ring_fill_level, &desc_list, &tail); } + +#ifdef QCA_ENHANCED_STATS_SUPPORT +void +dp_mon_populate_ppdu_usr_info_2_0(struct mon_rx_user_status *rx_user_status, + struct cdp_rx_stats_ppdu_user *ppdu_user) +{ + ppdu_user->mpdu_retries = rx_user_status->retry_mpdu; +} + +#ifdef WLAN_FEATURE_11BE +void dp_mon_rx_stats_update_2_0(struct dp_peer *peer, + struct cdp_rx_indication_ppdu *ppdu, + struct cdp_rx_stats_ppdu_user *ppdu_user) +{ + uint8_t mcs, preamble, ppdu_type; + + preamble = ppdu->u.preamble; + ppdu_type = ppdu->u.ppdu_type; + if (ppdu_type == HAL_RX_TYPE_SU) + mcs = ppdu->u.mcs; + else + mcs = ppdu_user->mcs; + + DP_STATS_INC(peer, rx.mpdu_retry_cnt, ppdu_user->mpdu_retries); + DP_STATS_INCC(peer, + rx.su_be_ppdu_cnt.mcs_count[MAX_MCS - 1], 1, + ((mcs >= (MAX_MCS - 1)) && (preamble == DOT11_BE) && + (ppdu_type == HAL_RX_TYPE_SU))); + DP_STATS_INCC(peer, + rx.su_be_ppdu_cnt.mcs_count[mcs], 1, + ((mcs < (MAX_MCS - 1)) && (preamble == DOT11_BE) && + (ppdu_type == HAL_RX_TYPE_SU))); + DP_STATS_INCC(peer, + rx.rx_mu_be[TXRX_TYPE_MU_OFDMA].ppdu.mcs_count[MAX_MCS - 1], + 1, ((mcs >= (MAX_MCS - 1)) && + (preamble == DOT11_BE) && + (ppdu_type == HAL_RX_TYPE_MU_OFDMA))); + DP_STATS_INCC(peer, + rx.rx_mu_be[TXRX_TYPE_MU_OFDMA].ppdu.mcs_count[mcs], + 1, ((mcs < (MAX_MCS - 1)) && + (preamble == DOT11_BE) && + (ppdu_type == HAL_RX_TYPE_MU_OFDMA))); + DP_STATS_INCC(peer, + rx.rx_mu_be[TXRX_TYPE_MU_MIMO].ppdu.mcs_count[MAX_MCS - 1], + 1, ((mcs >= (MAX_MCS - 1)) && + (preamble == DOT11_BE) && + (ppdu_type == HAL_RX_TYPE_MU_MIMO))); + DP_STATS_INCC(peer, + rx.rx_mu_be[TXRX_TYPE_MU_MIMO].ppdu.mcs_count[mc], + 1, ((mcs < (MAX_MCS - 1)) && + (preamble == DOT11_BE) && + (ppdu_type == HAL_RX_TYPE_MU_MIMO))); +} + +void +dp_mon_populate_ppdu_info_2_0(struct hal_rx_ppdu_info *hal_ppdu_info, + struct cdp_rx_indication_ppdu *ppdu) +{ + ppdu->punc_bw = hal_ppdu_info->rx_status.punctured_bw; +} +#else +void dp_mon_rx_stats_update_2_0(struct dp_peer *peer, + struct cdp_rx_indication_ppdu *ppdu, + struct cdp_rx_stats_ppdu_user *ppdu_user) +{ + DP_STATS_INC(peer, rx.mpdu_retry_cnt, ppdu_user->mpdu_retries); +} + +void +dp_mon_populate_ppdu_info_2_0(struct hal_rx_ppdu_info *hal_ppdu_info, + struct cdp_rx_indication_ppdu *ppdu) +{ + ppdu->punc_bw = 0; +} +#endif diff --git a/dp/wifi3.0/monitor/dp_mon.h b/dp/wifi3.0/monitor/dp_mon.h index 8213c32bea..3e61e90218 100644 --- a/dp/wifi3.0/monitor/dp_mon.h +++ b/dp/wifi3.0/monitor/dp_mon.h @@ -568,6 +568,15 @@ struct dp_mon_ops { void (*mon_register_intr_ops)(struct dp_soc *soc); #endif void (*mon_register_feature_ops)(struct dp_soc *soc); +#ifdef QCA_ENHANCED_STATS_SUPPORT + void (*mon_rx_stats_update)(struct dp_peer *peer, + struct cdp_rx_indication_ppdu *ppdu, + struct cdp_rx_stats_ppdu_user *ppdu_user); + void (*mon_rx_populate_ppdu_usr_info)(struct mon_rx_user_status *rx_user_status, + struct cdp_rx_stats_ppdu_user *ppdu_user); + void (*mon_rx_populate_ppdu_info)(struct hal_rx_ppdu_info *hal_ppdu_info, + struct cdp_rx_indication_ppdu *ppdu); +#endif }; struct dp_mon_soc { diff --git a/dp/wifi3.0/monitor/dp_rx_mon.c b/dp/wifi3.0/monitor/dp_rx_mon.c index d4352b7ddc..5ef27619ca 100644 --- a/dp/wifi3.0/monitor/dp_rx_mon.c +++ b/dp/wifi3.0/monitor/dp_rx_mon.c @@ -404,6 +404,7 @@ dp_rx_populate_cdp_indication_ppdu_user(struct dp_pdev *pdev, int ru_size; bool is_data = false; uint32_t num_users; + struct dp_mon_ops *mon_ops; num_users = ppdu_info->com_info.num_users; for (i = 0; i < num_users; i++) { @@ -493,6 +494,11 @@ dp_rx_populate_cdp_indication_ppdu_user(struct dp_pdev *pdev, rx_stats_peruser->vdev_id = peer->vdev->vdev_id; rx_stats_peruser->mu_ul_info_valid = 0; + mon_ops = dp_mon_ops_get(soc); + if (mon_ops && mon_ops->mon_rx_populate_ppdu_usr_info) + mon_ops->mon_rx_populate_ppdu_usr_info(rx_user_status, + rx_stats_peruser); + dp_peer_unref_delete(peer, DP_MOD_ID_RX_PPDU_STATS); if (cdp_rx_ppdu->u.ppdu_type == HAL_RX_TYPE_MU_OFDMA || cdp_rx_ppdu->u.ppdu_type == HAL_RX_TYPE_MU_MIMO) { @@ -546,6 +552,7 @@ dp_rx_populate_cdp_indication_ppdu(struct dp_pdev *pdev, struct dp_ast_entry *ast_entry; uint32_t ast_index; uint32_t i; + struct dp_mon_ops *mon_ops; cdp_rx_ppdu->first_data_seq_ctrl = ppdu_info->rx_status.first_data_seq_ctrl; @@ -635,6 +642,11 @@ dp_rx_populate_cdp_indication_ppdu(struct dp_pdev *pdev, dp_rx_populate_su_evm_details(ppdu_info, cdp_rx_ppdu); cdp_rx_ppdu->rx_antenna = ppdu_info->rx_status.rx_antenna; + mon_ops = dp_mon_ops_get(pdev->soc); + if (mon_ops && mon_ops->mon_rx_populate_ppdu_info) + mon_ops->mon_rx_populate_ppdu_info(ppdu_info, + cdp_rx_ppdu); + cdp_rx_ppdu->nf = ppdu_info->rx_status.chan_noise_floor; for (i = 0; i < MAX_CHAIN; i++) cdp_rx_ppdu->per_chain_rssi[i] = ppdu_info->rx_status.rssi[i]; @@ -724,6 +736,65 @@ static inline void dp_rx_rate_stats_update(struct dp_peer *peer, peer->vdev->stats.rx.last_rx_rate = ratekbps; } +#ifdef WLAN_FEATURE_11BE +static inline uint8_t dp_get_bw_offset_frm_bw(struct dp_soc *soc, + enum CMN_BW_TYPES bw) +{ + uint8_t pkt_bw_offset; + + switch (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; + case CMN_BW_320MHZ: + pkt_bw_offset = PKT_BW_GAIN_320MHZ; + break; + default: + pkt_bw_offset = 0; + dp_rx_mon_status_debug("%pK: Invalid BW index = %d", + soc, bw); + } + + return pkt_bw_offset; +} +#else +static inline uint8_t dp_get_bw_offset_frm_bw(struct dp_soc *soc, + enum CMN_BW_TYPES bw) +{ + uint8_t pkt_bw_offset; + + switch (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; + dp_rx_mon_status_debug("%pK: Invalid BW index = %d", + soc, bw); + } + + return pkt_bw_offset; +} +#endif + static void dp_rx_stats_update(struct dp_pdev *pdev, struct cdp_rx_indication_ppdu *ppdu) { @@ -735,6 +806,7 @@ static void dp_rx_stats_update(struct dp_pdev *pdev, struct cdp_rx_stats_ppdu_user *ppdu_user; uint32_t i; enum cdp_mu_packet_type mu_pkt_type; + struct dp_mon_ops *mon_ops; if (pdev) soc = pdev->soc; @@ -768,25 +840,8 @@ static void dp_rx_stats_update(struct dp_pdev *pdev, } 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; - dp_rx_mon_status_debug("%pK: Invalid BW index = %d", - soc, ppdu->u.bw); - } + pkt_bw_offset = dp_get_bw_offset_frm_bw(soc, ppdu->u.bw); DP_STATS_UPD(peer, rx.snr, (ppdu->rssi + pkt_bw_offset)); if (peer->stats.rx.avg_snr == CDP_INVALID_SNR) @@ -907,6 +962,11 @@ static void dp_rx_stats_update(struct dp_pdev *pdev, if (ppdu->tid != HAL_TID_INVALID) DP_STATS_INC(peer, rx.wme_ac_type[ac], num_msdu); + + mon_ops = dp_mon_ops_get(soc); + if (mon_ops && mon_ops->mon_rx_stats_update) + mon_ops->mon_rx_stats_update(peer, ppdu, ppdu_user); + dp_peer_stats_notify(pdev, peer); DP_STATS_UPD(peer, rx.last_snr, ppdu->rssi); diff --git a/qdf/inc/qdf_nbuf.h b/qdf/inc/qdf_nbuf.h index 6239ee7c2f..baf12da9c1 100644 --- a/qdf/inc/qdf_nbuf.h +++ b/qdf/inc/qdf_nbuf.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -307,6 +308,8 @@ * @start_seq: starting sequence number * @ba_bitmap: 256 bit block ack bitmap * @add_rtap_ext2: add radiotap extension2 + * @mpdu_retry_cnt: Rx mpdu retry count + * @punctured_bw: puntured bw */ struct mon_rx_status { uint64_t tsft; @@ -394,6 +397,10 @@ struct mon_rx_status { uint16_t start_seq; uint32_t ba_bitmap[8]; bool add_rtap_ext2; + uint32_t mpdu_retry_cnt; +#ifdef WLAN_FEATURE_11BE + uint8_t punctured_bw; +#endif }; /** @@ -428,6 +435,7 @@ struct mon_rx_status { * @mpdu_ok_byte_count: mpdu byte count with fcs ok * @mpdu_err_byte_count: mpdu byte count with fcs err * @sw_peer_id: software peer id + * @retry_mpdu: mpdu retry count */ struct mon_rx_user_status { uint32_t mcs:4, @@ -459,6 +467,7 @@ struct mon_rx_user_status { uint32_t mpdu_ok_byte_count; uint32_t mpdu_err_byte_count; uint16_t sw_peer_id; + uint32_t retry_mpdu; }; /**