diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h index 8054a94a91..d472bf77a3 100644 --- a/dp/inc/cdp_txrx_cmn_struct.h +++ b/dp/inc/cdp_txrx_cmn_struct.h @@ -1817,6 +1817,7 @@ struct cdp_tx_mgmt_comp_info { * @vdev_id: VAP Id * @bar_num_users: BA response user count, based on completion common TLV * @num_users: Number of users + * @max_users: Number of users from USR_INFO TLV * @drop_reason: drop reason from flush status * @is_flush: is_flush is set based on flush tlv * @flow_type: tx flow type from flush status @@ -1842,13 +1843,13 @@ struct cdp_tx_mgmt_comp_info { * @bss_color: 6 bit value for full bss color * @doppler: value for doppler (will be 0 most of the times) * @spatial_reuse: value for spatial reuse used in radiotap HE header - * @user: per-User stats (array of per-user structures) * @bar_ppdu_id: BAR ppdu_id * @bar_tx_duration: BAR tx duration * @bar_ppdu_start_timestamp: BAR start timestamp * @bar_ppdu_end_timestamp: BAR end timestamp * @tlv_bitmap: tlv_bitmap for the PPDU * @sched_cmdid: schedule command id + * @user: per-User stats (array of per-user structures) */ struct cdp_tx_completion_ppdu { uint32_t ppdu_id; @@ -1856,6 +1857,7 @@ struct cdp_tx_completion_ppdu { uint16_t vdev_id; uint16_t bar_num_users; uint32_t num_users; + uint8_t max_users; uint8_t last_usr_index; uint32_t drop_reason; uint32_t is_flush:1, @@ -1882,13 +1884,13 @@ struct cdp_tx_completion_ppdu { uint8_t bss_color; uint8_t doppler; uint8_t spatial_reuse; - struct cdp_tx_completion_ppdu_user user[CDP_MU_MAX_USERS]; uint32_t bar_ppdu_id; uint32_t bar_tx_duration; uint32_t bar_ppdu_start_timestamp; uint32_t bar_ppdu_end_timestamp; uint32_t tlv_bitmap; uint16_t sched_cmdid; + struct cdp_tx_completion_ppdu_user user[]; }; /** diff --git a/dp/wifi3.0/dp_htt.c b/dp/wifi3.0/dp_htt.c index 8b8f02700e..52ac48716a 100644 --- a/dp/wifi3.0/dp_htt.c +++ b/dp/wifi3.0/dp_htt.c @@ -2172,14 +2172,14 @@ static uint8_t dp_get_ppdu_info_user_index(struct dp_pdev *pdev, /* Max users possible is 8 so user array index should * not exceed 7 */ - qdf_assert_always(user_index <= CDP_MU_MAX_USER_INDEX); + qdf_assert_always(user_index <= (ppdu_desc->max_users - 1)); return user_index; } } ppdu_info->last_user++; /* Max users possible is 8 so last user should not exceed 8 */ - qdf_assert_always(ppdu_info->last_user <= CDP_MU_MAX_USERS); + qdf_assert_always(ppdu_info->last_user <= ppdu_desc->max_users); return ppdu_info->last_user - 1; } @@ -2213,6 +2213,8 @@ static void dp_process_ppdu_stats_common_tlv(struct dp_pdev *pdev, ppdu_desc->num_users = HTT_PPDU_STATS_COMMON_TLV_NUM_USERS_GET(*tag_buf); + qdf_assert_always(ppdu_desc->num_users <= ppdu_desc->max_users); + tag_buf = start_tag_buf + HTT_GET_STATS_CMN_INDEX(QTYPE_FRM_TYPE); frame_type = HTT_PPDU_STATS_COMMON_TLV_FRM_TYPE_GET(*tag_buf); ppdu_desc->htt_frame_type = frame_type; @@ -3464,10 +3466,11 @@ void dp_ppdu_desc_deliver(struct dp_pdev *pdev, */ static struct ppdu_info *dp_get_ppdu_desc(struct dp_pdev *pdev, uint32_t ppdu_id, - uint8_t tlv_type) + uint8_t tlv_type, uint8_t max_users) { struct ppdu_info *ppdu_info = NULL; struct cdp_tx_completion_ppdu *ppdu_desc = NULL; + uint32_t size = 0; /* * Find ppdu_id node exists or not @@ -3528,6 +3531,9 @@ struct ppdu_info *dp_get_ppdu_desc(struct dp_pdev *pdev, uint32_t ppdu_id, qdf_mem_free(ppdu_info); } + size = sizeof(struct cdp_tx_completion_ppdu) + + (max_users * sizeof(struct cdp_tx_completion_ppdu_user)); + /* * Allocate new ppdu_info node */ @@ -3535,9 +3541,8 @@ struct ppdu_info *dp_get_ppdu_desc(struct dp_pdev *pdev, uint32_t ppdu_id, if (!ppdu_info) return NULL; - ppdu_info->nbuf = qdf_nbuf_alloc(pdev->soc->osdev, - sizeof(struct cdp_tx_completion_ppdu), 0, 4, - TRUE); + ppdu_info->nbuf = qdf_nbuf_alloc(pdev->soc->osdev, size, + 0, 4, TRUE); if (!ppdu_info->nbuf) { qdf_mem_free(ppdu_info); return NULL; @@ -3545,11 +3550,9 @@ struct ppdu_info *dp_get_ppdu_desc(struct dp_pdev *pdev, uint32_t ppdu_id, ppdu_info->ppdu_desc = (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf); - qdf_mem_zero(qdf_nbuf_data(ppdu_info->nbuf), - sizeof(struct cdp_tx_completion_ppdu)); + qdf_mem_zero(qdf_nbuf_data(ppdu_info->nbuf), size); - if (qdf_nbuf_put_tail(ppdu_info->nbuf, - sizeof(struct cdp_tx_completion_ppdu)) == NULL) { + if (qdf_nbuf_put_tail(ppdu_info->nbuf, size) == NULL) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "No tailroom for HTT PPDU"); qdf_nbuf_free(ppdu_info->nbuf); @@ -3559,6 +3562,8 @@ struct ppdu_info *dp_get_ppdu_desc(struct dp_pdev *pdev, uint32_t ppdu_id, return NULL; } + ppdu_info->ppdu_desc->max_users = max_users; + /** * No lock is needed because all PPDU TLVs are processed in * same context and this list is updated in same context @@ -3589,7 +3594,7 @@ static struct ppdu_info *dp_htt_process_tlv(struct dp_pdev *pdev, struct cdp_tx_completion_ppdu *ppdu_desc = NULL; struct dp_peer *peer; uint32_t i = 0; - + uint8_t max_users = CDP_MU_MAX_USERS; uint32_t *msg_word = (uint32_t *) qdf_nbuf_data(htt_t2h_msg); length = HTT_T2H_PPDU_STATS_PAYLOAD_SIZE_GET(*msg_word); @@ -3597,8 +3602,8 @@ static struct ppdu_info *dp_htt_process_tlv(struct dp_pdev *pdev, msg_word = msg_word + 1; ppdu_id = HTT_T2H_PPDU_STATS_PPDU_ID_GET(*msg_word); - msg_word = msg_word + 3; + while (length > 0) { tlv_buf = (uint8_t *)msg_word; tlv_type = HTT_STATS_TLV_TAG_GET(*msg_word); @@ -3628,9 +3633,22 @@ static struct ppdu_info *dp_htt_process_tlv(struct dp_pdev *pdev, continue; } - ppdu_info = dp_get_ppdu_desc(pdev, ppdu_id, tlv_type); + /* + * retrieve max_users if it's USERS_INFO, + * else, it's 1 for COMPLTN_FLUSH, + * else, use CDP_MU_MAX_USERS + */ + if (tlv_type == HTT_PPDU_STATS_USERS_INFO_TLV) { + max_users = + HTT_PPDU_STATS_USERS_INFO_TLV_MAX_USERS_GET(*(msg_word + 1)); + } else if (tlv_type == HTT_PPDU_STATS_USR_COMPLTN_FLUSH_TLV) { + max_users = 1; + } + + ppdu_info = dp_get_ppdu_desc(pdev, ppdu_id, tlv_type, max_users); if (!ppdu_info) return NULL; + ppdu_info->ppdu_desc->bss_color = pdev->rx_mon_recv_status.bsscolor; @@ -3678,6 +3696,8 @@ static struct ppdu_info *dp_htt_process_tlv(struct dp_pdev *pdev, (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_SCH_CMD_STATUS_TLV)) && ppdu_desc->delayed_ba) { + + qdf_assert_always(ppdu_desc->num_users <= ppdu_desc->max_users); for (i = 0; i < ppdu_desc->num_users; i++) { struct cdp_delayed_tx_completion_ppdu_user *delay_ppdu; uint64_t start_tsf; diff --git a/dp/wifi3.0/dp_internal.h b/dp/wifi3.0/dp_internal.h index b9508d8ec4..7168fa8982 100644 --- a/dp/wifi3.0/dp_internal.h +++ b/dp/wifi3.0/dp_internal.h @@ -36,22 +36,6 @@ /* Macro For NYSM value received in VHT TLV */ #define VHT_SGI_NYSM 3 -/* PPDU STATS CFG */ -#define DP_PPDU_STATS_CFG_ALL 0xFFFF - -/* PPDU stats mask sent to FW to enable enhanced stats */ -#define DP_PPDU_STATS_CFG_ENH_STATS 0xE67 -/* PPDU stats mask sent to FW to support debug sniffer feature */ -#define DP_PPDU_STATS_CFG_SNIFFER 0x2FFF -/* PPDU stats mask sent to FW to support BPR feature*/ -#define DP_PPDU_STATS_CFG_BPR 0x2000 -/* PPDU stats mask sent to FW to support BPR and enhanced stats feature */ -#define DP_PPDU_STATS_CFG_BPR_ENH (DP_PPDU_STATS_CFG_BPR | \ - DP_PPDU_STATS_CFG_ENH_STATS) -/* PPDU stats mask sent to FW to support BPR and pcktlog stats feature */ -#define DP_PPDU_STATS_CFG_BPR_PKTLOG (DP_PPDU_STATS_CFG_BPR | \ - DP_PPDU_TXLITE_STATS_BITMASK_CFG) - /** * Bitmap of HTT PPDU TLV types for Default mode */ @@ -63,6 +47,42 @@ (1 << HTT_PPDU_STATS_USR_COMPLTN_COMMON_TLV) | \ (1 << HTT_PPDU_STATS_USR_COMPLTN_ACK_BA_STATUS_TLV) +/* PPDU STATS CFG */ +#define DP_PPDU_STATS_CFG_ALL 0xFFFF + +/* PPDU stats mask sent to FW to enable enhanced stats */ +#define DP_PPDU_STATS_CFG_ENH_STATS \ + (HTT_PPDU_DEFAULT_TLV_BITMAP) | \ + (1 << HTT_PPDU_STATS_USR_COMPLTN_FLUSH_TLV) | \ + (1 << HTT_PPDU_STATS_USR_COMMON_ARRAY_TLV) | \ + (1 << HTT_PPDU_STATS_USERS_INFO_TLV) + +/* PPDU stats mask sent to FW to support debug sniffer feature */ +#define DP_PPDU_STATS_CFG_SNIFFER \ + (HTT_PPDU_DEFAULT_TLV_BITMAP) | \ + (1 << HTT_PPDU_STATS_USR_MPDU_ENQ_BITMAP_64_TLV) | \ + (1 << HTT_PPDU_STATS_USR_MPDU_ENQ_BITMAP_256_TLV) | \ + (1 << HTT_PPDU_STATS_USR_COMPLTN_BA_BITMAP_64_TLV) | \ + (1 << HTT_PPDU_STATS_USR_COMPLTN_BA_BITMAP_256_TLV) | \ + (1 << HTT_PPDU_STATS_USR_COMPLTN_FLUSH_TLV) | \ + (1 << HTT_PPDU_STATS_USR_COMPLTN_BA_BITMAP_256_TLV) | \ + (1 << HTT_PPDU_STATS_USR_COMPLTN_FLUSH_TLV) | \ + (1 << HTT_PPDU_STATS_USR_COMMON_ARRAY_TLV) | \ + (1 << HTT_PPDU_STATS_TX_MGMTCTRL_PAYLOAD_TLV) | \ + (1 << HTT_PPDU_STATS_USERS_INFO_TLV) + +/* PPDU stats mask sent to FW to support BPR feature*/ +#define DP_PPDU_STATS_CFG_BPR \ + (1 << HTT_PPDU_STATS_TX_MGMTCTRL_PAYLOAD_TLV) | \ + (1 << HTT_PPDU_STATS_USERS_INFO_TLV) + +/* PPDU stats mask sent to FW to support BPR and enhanced stats feature */ +#define DP_PPDU_STATS_CFG_BPR_ENH (DP_PPDU_STATS_CFG_BPR | \ + DP_PPDU_STATS_CFG_ENH_STATS) +/* PPDU stats mask sent to FW to support BPR and pcktlog stats feature */ +#define DP_PPDU_STATS_CFG_BPR_PKTLOG (DP_PPDU_STATS_CFG_BPR | \ + DP_PPDU_TXLITE_STATS_BITMASK_CFG) + /** * Bitmap of HTT PPDU delayed ba TLV types for Default mode */