diff --git a/dp/cmn_dp_api/dp_ratetable.c b/dp/cmn_dp_api/dp_ratetable.c index a11cbfe6f4..78bc187a1b 100644 --- a/dp/cmn_dp_api/dp_ratetable.c +++ b/dp/cmn_dp_api/dp_ratetable.c @@ -3209,17 +3209,20 @@ enum DP_CMN_MODULATION_TYPE dp_getmodulation( * preamble - preamble * @bw - Transmission Bandwidth * @rix: rate index to be populated + * @ratecode: ratecode * * return - rate in kbps */ uint32_t dp_getrateindex(uint32_t gi, uint16_t mcs, uint8_t nss, uint8_t preamble, - uint8_t bw, uint32_t *rix) + uint8_t bw, uint32_t *rix, uint16_t *ratecode) { uint32_t ratekbps = 0, res = RT_INVALID_INDEX; /* represents failure */ uint16_t rc; enum DP_CMN_MODULATION_TYPE mod; + /* For error case, where idx exceeds bountry limit */ + *ratecode = 0; mod = dp_getmodulation(preamble, bw); rc = mcs; @@ -3269,6 +3272,7 @@ dp_getrateindex(uint32_t gi, uint16_t mcs, uint8_t nss, uint8_t preamble, break; } } + *ratecode = dp_11abgnratetable.info[res].ratecode; done: *rix = res; diff --git a/dp/cmn_dp_api/dp_ratetable.h b/dp/cmn_dp_api/dp_ratetable.h index 8809515d7b..b22527a485 100644 --- a/dp/cmn_dp_api/dp_ratetable.h +++ b/dp/cmn_dp_api/dp_ratetable.h @@ -166,7 +166,7 @@ enum DP_CMN_MODULATION_TYPE dp_getmodulation( uint32_t dp_getrateindex(uint32_t gi, uint16_t mcs, uint8_t nss, uint8_t preamble, - uint8_t bw, uint32_t *rix); + uint8_t bw, uint32_t *rix, uint16_t *ratecode); int dp_rate_idx_to_kbps(uint8_t rate_idx, uint8_t gintval); diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h index c9e6754d11..818b97ba64 100644 --- a/dp/inc/cdp_txrx_cmn_struct.h +++ b/dp/inc/cdp_txrx_cmn_struct.h @@ -100,6 +100,10 @@ #define CDP_DATA_TID_MAX 8 #define CDP_DATA_NON_QOS_TID 16 + +#define CDP_NUM_SA_BW 4 +#define CDP_PERCENT_MACRO 100 +#define CDP_NUM_KB_IN_MB 1000 /* * advance rx monitor filter * */ @@ -1278,6 +1282,7 @@ struct cdp_delayed_tx_completion_ppdu_user { * @sa_tx_antenna: antenna in which packet is transmitted * @sa_max_rates: smart antenna tx feedback info max rates * @sa_goodput: smart antenna tx feedback info goodput + * @current_rate_per: Moving average per */ struct cdp_tx_completion_ppdu_user { uint32_t completion_status:8, @@ -1292,7 +1297,7 @@ struct cdp_tx_completion_ppdu_user { uint16_t mpdu_failed:16; uint32_t long_retries:4, short_retries:4, - tx_ratecode:8, + tx_ratecode:16, is_ampdu:1, ppdu_type:5; uint32_t success_bytes; @@ -1339,8 +1344,28 @@ struct cdp_tx_completion_ppdu_user { uint8_t sa_is_training; uint32_t rssi_chain[CDP_RSSI_CHAIN_LEN]; uint32_t sa_tx_antenna; - uint32_t sa_max_rates; + /*Max rates for BW: 20MHZ, 40MHZ and 80MHZ and 160MHZ + * |---------------------------------------| + * | 16 bits | 16 bits | 16 bits | 16 bits | + * | BW-1 | BW-2 | BW-3 | BW-4 | + * | /\ \ | + * | / \ \ | + * | / \ \ | + * | / \ \ | + * | / \ \ | + * | / \ \ | + * |/ \ \ | + * |[11|8] [5|8] \ | + * | BW1 PADDED \ | + * |---------------------------------------| + */ + uint16_t sa_max_rates[CDP_NUM_SA_BW]; uint32_t sa_goodput; + /* below field is used to calculate goodput in non-training period + * Note: As host is exposing goodput and hence current_rate_per is + * of no use. It is just for Host computation. + */ + uint32_t current_rate_per; }; /** @@ -1705,7 +1730,7 @@ struct cdp_rx_indication_ppdu { uint32_t retries; uint32_t rx_byte_count; - uint8_t rx_ratecode; + uint16_t rx_ratecode; uint8_t fcs_error_mpdus; uint16_t frame_ctrl; int8_t rssi_chain[SS_COUNT][MAX_BW]; diff --git a/dp/inc/cdp_txrx_stats_struct.h b/dp/inc/cdp_txrx_stats_struct.h index 9c0746ccf3..78640e195a 100644 --- a/dp/inc/cdp_txrx_stats_struct.h +++ b/dp/inc/cdp_txrx_stats_struct.h @@ -122,11 +122,6 @@ #define CDP_TXRX_RATECODE_PREM_MASK 0x3 #define CDP_TXRX_RATECODE_PREM_LSB 6 -#define CDP_TXRX_RATECODE(mcsb, nssb, premb) \ - (((mcsb) & CDP_TXRX_RATECODE_MCS_MASK) | \ - (((nssb) & CDP_TXRX_RATECODE_NSS_MASK) << CDP_TXRX_RATECODE_NSS_LSB) | \ - (((premb) & CDP_TXRX_RATECODE_PREM_MASK) << CDP_TXRX_RATECODE_PREM_LSB)) - /* * cdp_tx_transmit_type: Transmit type index * SU: SU Transmit type index diff --git a/dp/wifi3.0/dp_htt.c b/dp/wifi3.0/dp_htt.c index 87bc8967be..8b0f85d801 100644 --- a/dp/wifi3.0/dp_htt.c +++ b/dp/wifi3.0/dp_htt.c @@ -183,6 +183,7 @@ dp_tx_rate_stats_update(struct dp_peer *peer, uint32_t ratekbps = 0; uint64_t ppdu_tx_rate = 0; uint32_t rix; + uint16_t ratecode = 0; if (!peer || !ppdu) return; @@ -192,15 +193,25 @@ dp_tx_rate_stats_update(struct dp_peer *peer, ppdu->nss, ppdu->preamble, ppdu->bw, - &rix); + &rix, + &ratecode); DP_STATS_UPD(peer, tx.last_tx_rate, ratekbps); if (!ratekbps) return; + /* Calculate goodput in non-training period + * In training period, don't do anything as + * pending pkt is send as goodput. + */ + if ((!peer->bss_peer) && (!ppdu->sa_is_training)) { + ppdu->sa_goodput = ((ratekbps / CDP_NUM_KB_IN_MB) * + (CDP_PERCENT_MACRO - ppdu->current_rate_per)); + } ppdu->rix = rix; ppdu->tx_ratekbps = ratekbps; + ppdu->tx_ratecode = ratecode; peer->stats.tx.avg_tx_rate = dp_ath_rate_lpf(peer->stats.tx.avg_tx_rate, ratekbps); ppdu_tx_rate = dp_ath_rate_out(peer->stats.tx.avg_tx_rate); @@ -2332,6 +2343,7 @@ static void dp_process_ppdu_stats_user_cmpltn_common_tlv( struct cdp_tx_completion_ppdu *ppdu_desc; struct cdp_tx_completion_ppdu_user *ppdu_user_desc; uint8_t curr_user_index = 0; + uint8_t bw_iter; htt_ppdu_stats_user_cmpltn_common_tlv *dp_stats_buf = (htt_ppdu_stats_user_cmpltn_common_tlv *)tag_buf; @@ -2402,6 +2414,34 @@ static void dp_process_ppdu_stats_user_cmpltn_common_tlv( * htt_ppdu_stats_user_cmpltn_common_tlv */ ppdu_desc->bar_num_users++; + + tag_buf++; + for (bw_iter = 0; bw_iter < CDP_RSSI_CHAIN_LEN; bw_iter++) { + ppdu_user_desc->rssi_chain[bw_iter] = + HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_CHAIN_RSSI_GET(*tag_buf); + tag_buf++; + } + + ppdu_user_desc->sa_tx_antenna = + HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_TX_ANTENNA_MASK_GET(*tag_buf); + + tag_buf++; + ppdu_user_desc->sa_is_training = + HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_IS_TRAINING_GET(*tag_buf); + if (ppdu_user_desc->sa_is_training) { + ppdu_user_desc->sa_goodput = + HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_PENDING_TRAINING_PKTS_GET(*tag_buf); + } + + tag_buf++; + for (bw_iter = 0; bw_iter < CDP_NUM_SA_BW; bw_iter++) { + ppdu_user_desc->sa_max_rates[bw_iter] = + HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_MAX_RATES_GET(tag_buf[bw_iter]); + } + + tag_buf += CDP_NUM_SA_BW; + ppdu_user_desc->current_rate_per = + HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_CURRENT_RATE_PER_GET(*tag_buf); } /* diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 376f866c88..7aa7f53f21 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -7843,9 +7843,10 @@ static int dp_txrx_get_ratekbps(int preamb, int mcs, int htflag, int gintval) { uint32_t rix; + uint16_t ratecode; return dp_getrateindex((uint32_t)gintval, (uint16_t)mcs, 1, - (uint8_t)preamb, 1, &rix); + (uint8_t)preamb, 1, &rix, &ratecode); } #else static int dp_txrx_get_ratekbps(int preamb, int mcs, diff --git a/dp/wifi3.0/dp_rx_mon_status.c b/dp/wifi3.0/dp_rx_mon_status.c index 463bd60514..ddad46782c 100644 --- a/dp/wifi3.0/dp_rx_mon_status.c +++ b/dp/wifi3.0/dp_rx_mon_status.c @@ -401,6 +401,7 @@ static inline void dp_rx_rate_stats_update(struct dp_peer *peer, uint32_t ppdu_rx_rate = 0; uint32_t nss = 0; uint32_t rix; + uint16_t ratecode; if (!peer || !ppdu) return; @@ -415,7 +416,8 @@ static inline void dp_rx_rate_stats_update(struct dp_peer *peer, nss, ppdu->u.preamble, ppdu->u.bw, - &rix); + &rix, + &ratecode); if (!ratekbps) return; @@ -426,9 +428,7 @@ static inline void dp_rx_rate_stats_update(struct dp_peer *peer, ppdu_rx_rate = dp_ath_rate_out(peer->stats.rx.avg_rx_rate); DP_STATS_UPD(peer, rx.rnd_avg_rx_rate, ppdu_rx_rate); ppdu->rx_ratekbps = ratekbps; - ppdu->rx_ratecode = CDP_TXRX_RATECODE(ppdu->u.mcs, - nss, - ppdu->u.preamble); + ppdu->rx_ratecode = ratecode; if (peer->vdev) peer->vdev->stats.rx.last_rx_rate = ratekbps;