mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-15 01:01:56 -04:00
qcacmn: Add linked list logic to store per ppdu descriptor status tlv
Add linked list logic to hold all ppdu descriptor status in a list till all TLVs have been processed This design handles asynchronous arrival of tlvs from fw per ppdu Change-Id: Ib8943d7c826c0b441f58f0eaba7ae0bdc0539d9a
This commit is contained in:
parent
301a242a31
commit
b9e7d01e52
4 changed files with 383 additions and 153 deletions
|
|
@ -903,6 +903,8 @@ struct cdp_tx_completion_ppdu_user {
|
|||
* @num_users: Number of users
|
||||
* @num_mpdu: Number of MPDUs in PPDU
|
||||
* @num_msdu: Number of MSDUs in PPDU
|
||||
* @frame_type: frame SU or MU
|
||||
* @frame_ctrl: frame control of 80211 header
|
||||
* @channel: Channel informartion
|
||||
* @ack_rssi: RSSI value of last ack packet (units=dB above noise floor)
|
||||
* @tx_duration: PPDU airtime
|
||||
|
|
@ -918,6 +920,7 @@ struct cdp_tx_completion_ppdu {
|
|||
uint32_t num_mpdu:9,
|
||||
num_msdu:16;
|
||||
uint16_t frame_type;
|
||||
uint16_t frame_ctrl;
|
||||
uint16_t channel;
|
||||
uint16_t phy_mode;
|
||||
uint32_t ack_rssi;
|
||||
|
|
|
|||
|
|
@ -47,6 +47,33 @@ do { \
|
|||
} while (0)
|
||||
|
||||
#define HTT_MGMT_CTRL_TLV_RESERVERD_LEN 12
|
||||
/**
|
||||
* Bitmap of HTT PPDU TLV types for Default mode
|
||||
*/
|
||||
#define HTT_PPDU_DEFAULT_TLV_BITMAP \
|
||||
(1 << HTT_PPDU_STATS_COMMON_TLV) | \
|
||||
(1 << HTT_PPDU_STATS_USR_COMMON_TLV) | \
|
||||
(1 << HTT_PPDU_STATS_USR_RATE_TLV) | \
|
||||
(1 << HTT_PPDU_STATS_SCH_CMD_STATUS_TLV) | \
|
||||
(1 << HTT_PPDU_STATS_USR_COMPLTN_COMMON_TLV) | \
|
||||
(1 << HTT_PPDU_STATS_USR_COMPLTN_ACK_BA_STATUS_TLV)
|
||||
|
||||
/**
|
||||
* Bitmap of HTT PPDU TLV types for Sniffer mode
|
||||
*/
|
||||
#define HTT_PPDU_SNIFFER_AMPDU_TLV_BITMAP \
|
||||
(1 << HTT_PPDU_STATS_COMMON_TLV) | \
|
||||
(1 << HTT_PPDU_STATS_USR_COMMON_TLV) | \
|
||||
(1 << HTT_PPDU_STATS_USR_RATE_TLV) | \
|
||||
(1 << HTT_PPDU_STATS_SCH_CMD_STATUS_TLV) | \
|
||||
(1 << HTT_PPDU_STATS_USR_COMPLTN_COMMON_TLV) | \
|
||||
(1 << HTT_PPDU_STATS_USR_COMPLTN_ACK_BA_STATUS_TLV) | \
|
||||
(1 << HTT_PPDU_STATS_USR_COMPLTN_BA_BITMAP_64_TLV) | \
|
||||
(1 << HTT_PPDU_STATS_USR_MPDU_ENQ_BITMAP_64_TLV) | \
|
||||
(1 << HTT_PPDU_STATS_USR_COMPLTN_BA_BITMAP_256_TLV)
|
||||
|
||||
#define HTT_FRAMECTRL_DATATYPE 0x08
|
||||
#define HTT_PPDU_DESC_MAX_DEPTH 16
|
||||
|
||||
/*
|
||||
* dp_tx_stats_update() - Update per-peer statistics
|
||||
|
|
@ -1538,24 +1565,26 @@ void htt_t2h_stats_handler(void *context)
|
|||
}
|
||||
|
||||
/*
|
||||
* dp_get_ppdu_info_user_index: Find place holder for the received
|
||||
* ppdu stats info
|
||||
* dp_get_ppdu_info_user_index: Find and allocate a per-user descriptor for a PPDU,
|
||||
* if a new peer id arrives in a PPDU
|
||||
* pdev: DP pdev handle
|
||||
* @peer_id : peer unique identifier
|
||||
* @ppdu_info: per ppdu tlv structure
|
||||
*
|
||||
* return:user index to be populated
|
||||
*/
|
||||
#ifdef FEATURE_PERPKT_INFO
|
||||
static uint8_t dp_get_ppdu_info_user_index(struct dp_pdev *pdev,
|
||||
uint16_t peer_id)
|
||||
uint16_t peer_id,
|
||||
struct ppdu_info *ppdu_info)
|
||||
{
|
||||
uint8_t user_index = 0;
|
||||
struct cdp_tx_completion_ppdu *ppdu_desc;
|
||||
struct cdp_tx_completion_ppdu_user *ppdu_user_desc;
|
||||
|
||||
ppdu_desc =
|
||||
(struct cdp_tx_completion_ppdu *)qdf_nbuf_data(pdev->tx_ppdu_info.buf);
|
||||
ppdu_desc = (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
|
||||
|
||||
while ((user_index + 1) <= pdev->tx_ppdu_info.last_user) {
|
||||
while ((user_index + 1) <= ppdu_info->last_user) {
|
||||
ppdu_user_desc = &ppdu_desc->user[user_index];
|
||||
if (ppdu_user_desc->peer_id != peer_id) {
|
||||
user_index++;
|
||||
|
|
@ -1569,33 +1598,30 @@ static uint8_t dp_get_ppdu_info_user_index(struct dp_pdev *pdev,
|
|||
}
|
||||
}
|
||||
|
||||
pdev->tx_ppdu_info.last_user++;
|
||||
ppdu_info->last_user++;
|
||||
/* Max users possible is 8 so last user should not exceed 8 */
|
||||
qdf_assert_always(pdev->tx_ppdu_info.last_user <= CDP_MU_MAX_USERS);
|
||||
return pdev->tx_ppdu_info.last_user - 1;
|
||||
qdf_assert_always(ppdu_info->last_user <= CDP_MU_MAX_USERS);
|
||||
return ppdu_info->last_user - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_process_ppdu_stats_common_tlv: Process htt_ppdu_stats_common_tlv
|
||||
* pdev: DP pdev handle
|
||||
* @tag_buf: buffer containing the tlv htt_ppdu_stats_common_tlv
|
||||
* @ppdu_info: per ppdu tlv structure
|
||||
*
|
||||
* return:void
|
||||
*/
|
||||
static void dp_process_ppdu_stats_common_tlv(struct dp_pdev *pdev,
|
||||
uint32_t *tag_buf)
|
||||
uint32_t *tag_buf, struct ppdu_info *ppdu_info)
|
||||
{
|
||||
uint16_t frame_type;
|
||||
uint16_t freq;
|
||||
struct dp_soc *soc = NULL;
|
||||
struct cdp_tx_completion_ppdu *ppdu_desc;
|
||||
htt_ppdu_stats_common_tlv *dp_stats_buf =
|
||||
(htt_ppdu_stats_common_tlv *)tag_buf;
|
||||
struct cdp_tx_completion_ppdu *ppdu_desc = NULL;
|
||||
|
||||
ppdu_desc =
|
||||
(struct cdp_tx_completion_ppdu *)qdf_nbuf_data(pdev->tx_ppdu_info.buf);
|
||||
ppdu_desc = (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
|
||||
|
||||
ppdu_desc->ppdu_id = dp_stats_buf->ppdu_id;
|
||||
tag_buf += 2;
|
||||
ppdu_desc->num_users =
|
||||
HTT_PPDU_STATS_COMMON_TLV_NUM_USERS_GET(*tag_buf);
|
||||
|
|
@ -1633,11 +1659,13 @@ static void dp_process_ppdu_stats_common_tlv(struct dp_pdev *pdev,
|
|||
/*
|
||||
* dp_process_ppdu_stats_user_common_tlv: Process ppdu_stats_user_common
|
||||
* @tag_buf: buffer containing the tlv htt_ppdu_stats_user_common_tlv
|
||||
* @ppdu_info: per ppdu tlv structure
|
||||
*
|
||||
* return:void
|
||||
*/
|
||||
static void dp_process_ppdu_stats_user_common_tlv(
|
||||
struct dp_pdev *pdev, uint32_t *tag_buf)
|
||||
struct dp_pdev *pdev, uint32_t *tag_buf,
|
||||
struct ppdu_info *ppdu_info)
|
||||
{
|
||||
uint16_t peer_id;
|
||||
struct dp_peer *peer;
|
||||
|
|
@ -1645,8 +1673,7 @@ static void dp_process_ppdu_stats_user_common_tlv(
|
|||
struct cdp_tx_completion_ppdu_user *ppdu_user_desc;
|
||||
uint8_t curr_user_index = 0;
|
||||
|
||||
ppdu_desc =
|
||||
(struct cdp_tx_completion_ppdu *) qdf_nbuf_data(pdev->tx_ppdu_info.buf);
|
||||
ppdu_desc = (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
|
||||
|
||||
tag_buf++;
|
||||
peer_id = HTT_PPDU_STATS_USER_COMMON_TLV_SW_PEER_ID_GET(*tag_buf);
|
||||
|
|
@ -1655,7 +1682,7 @@ static void dp_process_ppdu_stats_user_common_tlv(
|
|||
if (!peer)
|
||||
return;
|
||||
|
||||
curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id);
|
||||
curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
|
||||
ppdu_user_desc = &ppdu_desc->user[curr_user_index];
|
||||
|
||||
ppdu_user_desc->peer_id = peer_id;
|
||||
|
|
@ -1677,6 +1704,7 @@ static void dp_process_ppdu_stats_user_common_tlv(
|
|||
HTT_PPDU_STATS_USER_COMMON_TLV_QOS_CTRL_GET(*tag_buf);
|
||||
ppdu_user_desc->frame_ctrl =
|
||||
HTT_PPDU_STATS_USER_COMMON_TLV_FRAME_CTRL_GET(*tag_buf);
|
||||
ppdu_desc->frame_ctrl = ppdu_user_desc->frame_ctrl;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1684,11 +1712,13 @@ static void dp_process_ppdu_stats_user_common_tlv(
|
|||
* dp_process_ppdu_stats_user_rate_tlv() - Process htt_ppdu_stats_user_rate_tlv
|
||||
* @pdev: DP pdev handle
|
||||
* @tag_buf: T2H message buffer carrying the user rate TLV
|
||||
* @ppdu_info: per ppdu tlv structure
|
||||
*
|
||||
* return:void
|
||||
*/
|
||||
static void dp_process_ppdu_stats_user_rate_tlv(struct dp_pdev *pdev,
|
||||
uint32_t *tag_buf)
|
||||
uint32_t *tag_buf,
|
||||
struct ppdu_info *ppdu_info)
|
||||
{
|
||||
uint16_t peer_id;
|
||||
struct dp_peer *peer;
|
||||
|
|
@ -1696,8 +1726,7 @@ static void dp_process_ppdu_stats_user_rate_tlv(struct dp_pdev *pdev,
|
|||
struct cdp_tx_completion_ppdu_user *ppdu_user_desc;
|
||||
uint8_t curr_user_index = 0;
|
||||
|
||||
ppdu_desc =
|
||||
(struct cdp_tx_completion_ppdu *) qdf_nbuf_data(pdev->tx_ppdu_info.buf);
|
||||
ppdu_desc = (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
|
||||
|
||||
tag_buf++;
|
||||
peer_id = HTT_PPDU_STATS_USER_RATE_TLV_SW_PEER_ID_GET(*tag_buf);
|
||||
|
|
@ -1706,7 +1735,7 @@ static void dp_process_ppdu_stats_user_rate_tlv(struct dp_pdev *pdev,
|
|||
if (!peer)
|
||||
return;
|
||||
|
||||
curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id);
|
||||
curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
|
||||
|
||||
ppdu_user_desc = &ppdu_desc->user[curr_user_index];
|
||||
ppdu_user_desc->peer_id = peer_id;
|
||||
|
|
@ -1754,11 +1783,13 @@ static void dp_process_ppdu_stats_user_rate_tlv(struct dp_pdev *pdev,
|
|||
* htt_ppdu_stats_enq_mpdu_bitmap_64_tlv
|
||||
* pdev: DP PDEV handle
|
||||
* @tag_buf: buffer containing the tlv htt_ppdu_stats_enq_mpdu_bitmap_64_tlv
|
||||
* @ppdu_info: per ppdu tlv structure
|
||||
*
|
||||
* return:void
|
||||
*/
|
||||
static void dp_process_ppdu_stats_enq_mpdu_bitmap_64_tlv(
|
||||
struct dp_pdev *pdev, uint32_t *tag_buf)
|
||||
struct dp_pdev *pdev, uint32_t *tag_buf,
|
||||
struct ppdu_info *ppdu_info)
|
||||
{
|
||||
htt_ppdu_stats_enq_mpdu_bitmap_64_tlv *dp_stats_buf =
|
||||
(htt_ppdu_stats_enq_mpdu_bitmap_64_tlv *)tag_buf;
|
||||
|
|
@ -1769,8 +1800,7 @@ static void dp_process_ppdu_stats_enq_mpdu_bitmap_64_tlv(
|
|||
uint16_t peer_id;
|
||||
struct dp_peer *peer;
|
||||
|
||||
ppdu_desc =
|
||||
(struct cdp_tx_completion_ppdu *)qdf_nbuf_data(pdev->tx_ppdu_info.buf);
|
||||
ppdu_desc = (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
|
||||
|
||||
tag_buf++;
|
||||
|
||||
|
|
@ -1782,7 +1812,7 @@ static void dp_process_ppdu_stats_enq_mpdu_bitmap_64_tlv(
|
|||
if (!peer)
|
||||
return;
|
||||
|
||||
curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id);
|
||||
curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
|
||||
|
||||
ppdu_user_desc = &ppdu_desc->user[curr_user_index];
|
||||
ppdu_user_desc->peer_id = peer_id;
|
||||
|
|
@ -1797,11 +1827,13 @@ static void dp_process_ppdu_stats_enq_mpdu_bitmap_64_tlv(
|
|||
* htt_ppdu_stats_enq_mpdu_bitmap_256_tlv
|
||||
* soc: DP SOC handle
|
||||
* @tag_buf: buffer containing the tlv htt_ppdu_stats_enq_mpdu_bitmap_256_tlv
|
||||
* @ppdu_info: per ppdu tlv structure
|
||||
*
|
||||
* return:void
|
||||
*/
|
||||
static void dp_process_ppdu_stats_enq_mpdu_bitmap_256_tlv(
|
||||
struct dp_pdev *pdev, uint32_t *tag_buf)
|
||||
struct dp_pdev *pdev, uint32_t *tag_buf,
|
||||
struct ppdu_info *ppdu_info)
|
||||
{
|
||||
htt_ppdu_stats_enq_mpdu_bitmap_256_tlv *dp_stats_buf =
|
||||
(htt_ppdu_stats_enq_mpdu_bitmap_256_tlv *)tag_buf;
|
||||
|
|
@ -1812,8 +1844,7 @@ static void dp_process_ppdu_stats_enq_mpdu_bitmap_256_tlv(
|
|||
uint16_t peer_id;
|
||||
struct dp_peer *peer;
|
||||
|
||||
ppdu_desc =
|
||||
(struct cdp_tx_completion_ppdu *)qdf_nbuf_data(pdev->tx_ppdu_info.buf);
|
||||
ppdu_desc = (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
|
||||
|
||||
tag_buf++;
|
||||
|
||||
|
|
@ -1825,7 +1856,7 @@ static void dp_process_ppdu_stats_enq_mpdu_bitmap_256_tlv(
|
|||
if (!peer)
|
||||
return;
|
||||
|
||||
curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id);
|
||||
curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
|
||||
|
||||
ppdu_user_desc = &ppdu_desc->user[curr_user_index];
|
||||
ppdu_user_desc->peer_id = peer_id;
|
||||
|
|
@ -1840,11 +1871,13 @@ static void dp_process_ppdu_stats_enq_mpdu_bitmap_256_tlv(
|
|||
* htt_ppdu_stats_user_cmpltn_common_tlv
|
||||
* soc: DP SOC handle
|
||||
* @tag_buf: buffer containing the tlv htt_ppdu_stats_user_cmpltn_common_tlv
|
||||
* @ppdu_info: per ppdu tlv structure
|
||||
*
|
||||
* return:void
|
||||
*/
|
||||
static void dp_process_ppdu_stats_user_cmpltn_common_tlv(
|
||||
struct dp_pdev *pdev, uint32_t *tag_buf)
|
||||
struct dp_pdev *pdev, uint32_t *tag_buf,
|
||||
struct ppdu_info *ppdu_info)
|
||||
{
|
||||
uint16_t peer_id;
|
||||
struct dp_peer *peer;
|
||||
|
|
@ -1854,8 +1887,7 @@ static void dp_process_ppdu_stats_user_cmpltn_common_tlv(
|
|||
htt_ppdu_stats_user_cmpltn_common_tlv *dp_stats_buf =
|
||||
(htt_ppdu_stats_user_cmpltn_common_tlv *)tag_buf;
|
||||
|
||||
ppdu_desc =
|
||||
(struct cdp_tx_completion_ppdu *)qdf_nbuf_data(pdev->tx_ppdu_info.buf);
|
||||
ppdu_desc = (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
|
||||
|
||||
tag_buf++;
|
||||
peer_id =
|
||||
|
|
@ -1865,7 +1897,7 @@ static void dp_process_ppdu_stats_user_cmpltn_common_tlv(
|
|||
if (!peer)
|
||||
return;
|
||||
|
||||
curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id);
|
||||
curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
|
||||
ppdu_user_desc = &ppdu_desc->user[curr_user_index];
|
||||
ppdu_user_desc->peer_id = peer_id;
|
||||
|
||||
|
|
@ -1897,6 +1929,7 @@ static void dp_process_ppdu_stats_user_cmpltn_common_tlv(
|
|||
|
||||
ppdu_user_desc->is_ampdu =
|
||||
HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_IS_AMPDU_GET(*tag_buf);
|
||||
ppdu_info->is_ampdu = ppdu_user_desc->is_ampdu;
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1905,11 +1938,13 @@ static void dp_process_ppdu_stats_user_cmpltn_common_tlv(
|
|||
* htt_ppdu_stats_user_compltn_ba_bitmap_64_tlv
|
||||
* pdev: DP PDEV handle
|
||||
* @tag_buf: buffer containing the htt_ppdu_stats_user_compltn_ba_bitmap_64_tlv
|
||||
* @ppdu_info: per ppdu tlv structure
|
||||
*
|
||||
* return:void
|
||||
*/
|
||||
static void dp_process_ppdu_stats_user_compltn_ba_bitmap_64_tlv(
|
||||
struct dp_pdev *pdev, uint32_t *tag_buf)
|
||||
struct dp_pdev *pdev, uint32_t *tag_buf,
|
||||
struct ppdu_info *ppdu_info)
|
||||
{
|
||||
htt_ppdu_stats_user_compltn_ba_bitmap_64_tlv *dp_stats_buf =
|
||||
(htt_ppdu_stats_user_compltn_ba_bitmap_64_tlv *)tag_buf;
|
||||
|
|
@ -1919,8 +1954,7 @@ static void dp_process_ppdu_stats_user_compltn_ba_bitmap_64_tlv(
|
|||
uint16_t peer_id;
|
||||
struct dp_peer *peer;
|
||||
|
||||
ppdu_desc =
|
||||
(struct cdp_tx_completion_ppdu *)qdf_nbuf_data(pdev->tx_ppdu_info.buf);
|
||||
ppdu_desc = (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
|
||||
|
||||
tag_buf++;
|
||||
|
||||
|
|
@ -1932,7 +1966,7 @@ static void dp_process_ppdu_stats_user_compltn_ba_bitmap_64_tlv(
|
|||
if (!peer)
|
||||
return;
|
||||
|
||||
curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id);
|
||||
curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
|
||||
|
||||
ppdu_user_desc = &ppdu_desc->user[curr_user_index];
|
||||
ppdu_user_desc->peer_id = peer_id;
|
||||
|
|
@ -1947,11 +1981,13 @@ static void dp_process_ppdu_stats_user_compltn_ba_bitmap_64_tlv(
|
|||
* htt_ppdu_stats_user_compltn_ba_bitmap_256_tlv
|
||||
* pdev: DP PDEV handle
|
||||
* @tag_buf: buffer containing the htt_ppdu_stats_user_compltn_ba_bitmap_256_tlv
|
||||
* @ppdu_info: per ppdu tlv structure
|
||||
*
|
||||
* return:void
|
||||
*/
|
||||
static void dp_process_ppdu_stats_user_compltn_ba_bitmap_256_tlv(
|
||||
struct dp_pdev *pdev, uint32_t *tag_buf)
|
||||
struct dp_pdev *pdev, uint32_t *tag_buf,
|
||||
struct ppdu_info *ppdu_info)
|
||||
{
|
||||
htt_ppdu_stats_user_compltn_ba_bitmap_256_tlv *dp_stats_buf =
|
||||
(htt_ppdu_stats_user_compltn_ba_bitmap_256_tlv *)tag_buf;
|
||||
|
|
@ -1961,8 +1997,7 @@ static void dp_process_ppdu_stats_user_compltn_ba_bitmap_256_tlv(
|
|||
uint16_t peer_id;
|
||||
struct dp_peer *peer;
|
||||
|
||||
ppdu_desc =
|
||||
(struct cdp_tx_completion_ppdu *)qdf_nbuf_data(pdev->tx_ppdu_info.buf);
|
||||
ppdu_desc = (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
|
||||
|
||||
tag_buf++;
|
||||
|
||||
|
|
@ -1974,7 +2009,7 @@ static void dp_process_ppdu_stats_user_compltn_ba_bitmap_256_tlv(
|
|||
if (!peer)
|
||||
return;
|
||||
|
||||
curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id);
|
||||
curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
|
||||
|
||||
ppdu_user_desc = &ppdu_desc->user[curr_user_index];
|
||||
ppdu_user_desc->peer_id = peer_id;
|
||||
|
|
@ -1989,11 +2024,13 @@ static void dp_process_ppdu_stats_user_compltn_ba_bitmap_256_tlv(
|
|||
* htt_ppdu_stats_user_compltn_ack_ba_status_tlv
|
||||
* pdev: DP PDE handle
|
||||
* @tag_buf: buffer containing the htt_ppdu_stats_user_compltn_ack_ba_status_tlv
|
||||
* @ppdu_info: per ppdu tlv structure
|
||||
*
|
||||
* return:void
|
||||
*/
|
||||
static void dp_process_ppdu_stats_user_compltn_ack_ba_status_tlv(
|
||||
struct dp_pdev *pdev, uint32_t *tag_buf)
|
||||
struct dp_pdev *pdev, uint32_t *tag_buf,
|
||||
struct ppdu_info *ppdu_info)
|
||||
{
|
||||
uint16_t peer_id;
|
||||
struct dp_peer *peer;
|
||||
|
|
@ -2001,29 +2038,31 @@ static void dp_process_ppdu_stats_user_compltn_ack_ba_status_tlv(
|
|||
struct cdp_tx_completion_ppdu_user *ppdu_user_desc;
|
||||
uint8_t curr_user_index = 0;
|
||||
|
||||
ppdu_desc =
|
||||
(struct cdp_tx_completion_ppdu *)qdf_nbuf_data(pdev->tx_ppdu_info.buf);
|
||||
ppdu_desc = (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
|
||||
|
||||
tag_buf += 2;
|
||||
peer_id =
|
||||
HTT_PPDU_STATS_USER_CMPLTN_ACK_BA_STATUS_TLV_SW_PEER_ID_GET(*tag_buf);
|
||||
|
||||
|
||||
peer = dp_peer_find_by_id(pdev->soc, peer_id);
|
||||
|
||||
if (!peer)
|
||||
return;
|
||||
|
||||
curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id);
|
||||
curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
|
||||
|
||||
ppdu_user_desc = &ppdu_desc->user[curr_user_index];
|
||||
ppdu_user_desc->peer_id = peer_id;
|
||||
|
||||
tag_buf++;
|
||||
ppdu_user_desc->tid =
|
||||
HTT_PPDU_STATS_USER_CMPLTN_ACK_BA_STATUS_TLV_TID_NUM_GET(*tag_buf);
|
||||
ppdu_user_desc->num_mpdu =
|
||||
HTT_PPDU_STATS_USER_CMPLTN_ACK_BA_STATUS_TLV_NUM_MPDU_GET(*tag_buf);
|
||||
HTT_PPDU_STATS_USER_CMPLTN_ACK_BA_STATUS_TLV_NUM_MPDU_GET(*tag_buf);
|
||||
|
||||
ppdu_user_desc->num_msdu =
|
||||
HTT_PPDU_STATS_USER_CMPLTN_ACK_BA_STATUS_TLV_NUM_MSDU_GET(*tag_buf);
|
||||
HTT_PPDU_STATS_USER_CMPLTN_ACK_BA_STATUS_TLV_NUM_MSDU_GET(*tag_buf);
|
||||
|
||||
ppdu_user_desc->success_msdus = ppdu_user_desc->num_msdu;
|
||||
|
||||
|
|
@ -2037,11 +2076,13 @@ static void dp_process_ppdu_stats_user_compltn_ack_ba_status_tlv(
|
|||
* htt_ppdu_stats_user_common_array_tlv
|
||||
* pdev: DP PDEV handle
|
||||
* @tag_buf: buffer containing the htt_ppdu_stats_user_compltn_ack_ba_status_tlv
|
||||
* @ppdu_info: per ppdu tlv structure
|
||||
*
|
||||
* return:void
|
||||
*/
|
||||
static void dp_process_ppdu_stats_user_common_array_tlv(struct dp_pdev *pdev,
|
||||
uint32_t *tag_buf)
|
||||
static void dp_process_ppdu_stats_user_common_array_tlv(
|
||||
struct dp_pdev *pdev, uint32_t *tag_buf,
|
||||
struct ppdu_info *ppdu_info)
|
||||
{
|
||||
uint32_t peer_id;
|
||||
struct dp_peer *peer;
|
||||
|
|
@ -2050,8 +2091,7 @@ static void dp_process_ppdu_stats_user_common_array_tlv(struct dp_pdev *pdev,
|
|||
uint8_t curr_user_index = 0;
|
||||
struct htt_tx_ppdu_stats_info *dp_stats_buf;
|
||||
|
||||
ppdu_desc =
|
||||
(struct cdp_tx_completion_ppdu *)qdf_nbuf_data(pdev->tx_ppdu_info.buf);
|
||||
ppdu_desc = (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
|
||||
|
||||
tag_buf++;
|
||||
dp_stats_buf = (struct htt_tx_ppdu_stats_info *)tag_buf;
|
||||
|
|
@ -2067,7 +2107,7 @@ static void dp_process_ppdu_stats_user_common_array_tlv(struct dp_pdev *pdev,
|
|||
return;
|
||||
}
|
||||
|
||||
curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id);
|
||||
curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
|
||||
|
||||
ppdu_user_desc = &ppdu_desc->user[curr_user_index];
|
||||
|
||||
|
|
@ -2167,94 +2207,275 @@ static void dp_process_ppdu_stats_tx_mgmtctrl_payload_tlv(
|
|||
|
||||
/**
|
||||
* dp_process_ppdu_tag(): Function to process the PPDU TLVs
|
||||
* @soc: DP Physical device (radio) handle
|
||||
* @pdev: DP pdev handle
|
||||
* @tag_buf: TLV buffer
|
||||
* @tlv_len: length of tlv
|
||||
* @ppdu_info: per ppdu tlv structure
|
||||
*
|
||||
* return: void
|
||||
*/
|
||||
static void dp_process_ppdu_tag(struct dp_pdev *pdev, uint32_t *tag_buf,
|
||||
uint32_t tlv_len)
|
||||
uint32_t tlv_len, struct ppdu_info *ppdu_info)
|
||||
{
|
||||
uint32_t tlv_type = HTT_STATS_TLV_TAG_GET(*tag_buf);
|
||||
|
||||
switch (tlv_type) {
|
||||
case HTT_PPDU_STATS_COMMON_TLV:
|
||||
qdf_assert_always(tlv_len ==
|
||||
sizeof(htt_ppdu_stats_common_tlv));
|
||||
dp_process_ppdu_stats_common_tlv(pdev, tag_buf);
|
||||
dp_process_ppdu_stats_common_tlv(pdev, tag_buf, ppdu_info);
|
||||
break;
|
||||
case HTT_PPDU_STATS_USR_COMMON_TLV:
|
||||
qdf_assert_always(tlv_len ==
|
||||
sizeof(htt_ppdu_stats_user_common_tlv));
|
||||
dp_process_ppdu_stats_user_common_tlv(pdev, tag_buf);
|
||||
dp_process_ppdu_stats_user_common_tlv(
|
||||
pdev, tag_buf, ppdu_info);
|
||||
break;
|
||||
case HTT_PPDU_STATS_USR_RATE_TLV:
|
||||
qdf_assert_always(tlv_len ==
|
||||
sizeof(htt_ppdu_stats_user_rate_tlv));
|
||||
dp_process_ppdu_stats_user_rate_tlv(pdev, tag_buf);
|
||||
dp_process_ppdu_stats_user_rate_tlv(pdev, tag_buf, ppdu_info);
|
||||
break;
|
||||
case HTT_PPDU_STATS_USR_MPDU_ENQ_BITMAP_64_TLV:
|
||||
qdf_assert_always(tlv_len ==
|
||||
sizeof(htt_ppdu_stats_enq_mpdu_bitmap_64_tlv));
|
||||
dp_process_ppdu_stats_enq_mpdu_bitmap_64_tlv(pdev, tag_buf);
|
||||
dp_process_ppdu_stats_enq_mpdu_bitmap_64_tlv(
|
||||
pdev, tag_buf, ppdu_info);
|
||||
break;
|
||||
case HTT_PPDU_STATS_USR_MPDU_ENQ_BITMAP_256_TLV:
|
||||
qdf_assert_always(tlv_len ==
|
||||
sizeof(htt_ppdu_stats_enq_mpdu_bitmap_256_tlv));
|
||||
dp_process_ppdu_stats_enq_mpdu_bitmap_256_tlv(pdev, tag_buf);
|
||||
dp_process_ppdu_stats_enq_mpdu_bitmap_256_tlv(
|
||||
pdev, tag_buf, ppdu_info);
|
||||
break;
|
||||
case HTT_PPDU_STATS_USR_COMPLTN_COMMON_TLV:
|
||||
qdf_assert_always(tlv_len ==
|
||||
sizeof(htt_ppdu_stats_user_cmpltn_common_tlv));
|
||||
dp_process_ppdu_stats_user_cmpltn_common_tlv(pdev, tag_buf);
|
||||
dp_process_ppdu_stats_user_cmpltn_common_tlv(
|
||||
pdev, tag_buf, ppdu_info);
|
||||
break;
|
||||
case HTT_PPDU_STATS_USR_COMPLTN_BA_BITMAP_64_TLV:
|
||||
qdf_assert_always(tlv_len ==
|
||||
sizeof(htt_ppdu_stats_user_compltn_ba_bitmap_64_tlv));
|
||||
dp_process_ppdu_stats_user_compltn_ba_bitmap_64_tlv(pdev,
|
||||
tag_buf);
|
||||
dp_process_ppdu_stats_user_compltn_ba_bitmap_64_tlv(
|
||||
pdev, tag_buf, ppdu_info);
|
||||
break;
|
||||
case HTT_PPDU_STATS_USR_COMPLTN_BA_BITMAP_256_TLV:
|
||||
qdf_assert_always(tlv_len ==
|
||||
sizeof(htt_ppdu_stats_user_compltn_ba_bitmap_256_tlv));
|
||||
dp_process_ppdu_stats_user_compltn_ba_bitmap_256_tlv(pdev,
|
||||
tag_buf);
|
||||
dp_process_ppdu_stats_user_compltn_ba_bitmap_256_tlv(
|
||||
pdev, tag_buf, ppdu_info);
|
||||
break;
|
||||
case HTT_PPDU_STATS_USR_COMPLTN_ACK_BA_STATUS_TLV:
|
||||
qdf_assert_always(tlv_len ==
|
||||
sizeof(htt_ppdu_stats_user_compltn_ack_ba_status_tlv));
|
||||
dp_process_ppdu_stats_user_compltn_ack_ba_status_tlv(pdev,
|
||||
tag_buf);
|
||||
dp_process_ppdu_stats_user_compltn_ack_ba_status_tlv(
|
||||
pdev, tag_buf, ppdu_info);
|
||||
break;
|
||||
case HTT_PPDU_STATS_USR_COMMON_ARRAY_TLV:
|
||||
qdf_assert_always(tlv_len ==
|
||||
sizeof(htt_ppdu_stats_usr_common_array_tlv_v));
|
||||
dp_process_ppdu_stats_user_common_array_tlv(pdev,
|
||||
tag_buf);
|
||||
dp_process_ppdu_stats_user_common_array_tlv(
|
||||
pdev, tag_buf, ppdu_info);
|
||||
break;
|
||||
case HTT_PPDU_STATS_USR_COMPLTN_FLUSH_TLV:
|
||||
qdf_assert_always(tlv_len ==
|
||||
sizeof(htt_ppdu_stats_flush_tlv));
|
||||
dp_process_ppdu_stats_user_compltn_flush_tlv(pdev,
|
||||
tag_buf);
|
||||
dp_process_ppdu_stats_user_compltn_flush_tlv(
|
||||
pdev, tag_buf);
|
||||
break;
|
||||
case HTT_PPDU_STATS_TX_MGMTCTRL_PAYLOAD_TLV:
|
||||
dp_process_ppdu_stats_tx_mgmtctrl_payload_tlv(pdev,
|
||||
tag_buf, tlv_len);
|
||||
dp_process_ppdu_stats_tx_mgmtctrl_payload_tlv(
|
||||
pdev, tag_buf, tlv_len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static QDF_STATUS dp_htt_process_tlv(struct dp_pdev *pdev,
|
||||
/**
|
||||
* dp_ppdu_desc_deliver(): Function to deliver Tx PPDU status descriptor
|
||||
* to upper layer
|
||||
* @pdev: DP pdev handle
|
||||
* @ppdu_info: per PPDU TLV descriptor
|
||||
*
|
||||
* return: void
|
||||
*/
|
||||
static
|
||||
void dp_ppdu_desc_deliver(struct dp_pdev *pdev,
|
||||
struct ppdu_info *ppdu_info)
|
||||
{
|
||||
struct cdp_tx_completion_ppdu *ppdu_desc = NULL;
|
||||
struct dp_peer *peer = NULL;
|
||||
qdf_nbuf_t nbuf;
|
||||
uint16_t i;
|
||||
|
||||
ppdu_desc = (struct cdp_tx_completion_ppdu *)
|
||||
qdf_nbuf_data(ppdu_info->nbuf);
|
||||
|
||||
ppdu_desc->num_users = ppdu_info->last_user;
|
||||
ppdu_desc->ppdu_id = ppdu_info->ppdu_id;
|
||||
|
||||
for (i = 0; i < ppdu_desc->num_users; i++) {
|
||||
|
||||
|
||||
ppdu_desc->num_mpdu += ppdu_desc->user[i].num_mpdu;
|
||||
ppdu_desc->num_msdu += ppdu_desc->user[i].num_msdu;
|
||||
|
||||
if (ppdu_desc->user[i].tid < CDP_DATA_TID_MAX) {
|
||||
peer = dp_peer_find_by_id(pdev->soc,
|
||||
ppdu_desc->user[i].peer_id);
|
||||
/**
|
||||
* This check is to make sure peer is not deleted
|
||||
* after processing the TLVs.
|
||||
*/
|
||||
if (!peer)
|
||||
continue;
|
||||
|
||||
dp_tx_stats_update(pdev->soc, peer,
|
||||
&ppdu_desc->user[i],
|
||||
ppdu_desc->ack_rssi);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove from the list
|
||||
*/
|
||||
TAILQ_REMOVE(&pdev->ppdu_info_list, ppdu_info, ppdu_info_list_elem);
|
||||
nbuf = ppdu_info->nbuf;
|
||||
pdev->list_depth--;
|
||||
qdf_mem_free(ppdu_info);
|
||||
|
||||
qdf_assert_always(nbuf);
|
||||
|
||||
ppdu_desc = (struct cdp_tx_completion_ppdu *)
|
||||
qdf_nbuf_data(nbuf);
|
||||
|
||||
/**
|
||||
* Deliver PPDU stats only for valid (acked) data frames if
|
||||
* sniffer mode is not enabled.
|
||||
* If sniffer mode is enabled, PPDU stats for all frames
|
||||
* including mgmt/control frames should be delivered to upper layer
|
||||
*/
|
||||
if (pdev->tx_sniffer_enable || pdev->mcopy_mode) {
|
||||
dp_wdi_event_handler(WDI_EVENT_TX_PPDU_DESC, pdev->soc,
|
||||
nbuf, HTT_INVALID_PEER,
|
||||
WDI_NO_VAL, pdev->pdev_id);
|
||||
} else {
|
||||
if (ppdu_desc->num_mpdu != 0 && ppdu_desc->num_users != 0 &&
|
||||
ppdu_desc->frame_ctrl & HTT_FRAMECTRL_DATATYPE) {
|
||||
|
||||
dp_wdi_event_handler(WDI_EVENT_TX_PPDU_DESC,
|
||||
pdev->soc, nbuf, HTT_INVALID_PEER,
|
||||
WDI_NO_VAL, pdev->pdev_id);
|
||||
} else
|
||||
qdf_nbuf_free(nbuf);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_get_ppdu_desc(): Function to allocate new PPDU status
|
||||
* desc for new ppdu id
|
||||
* @pdev: DP pdev handle
|
||||
* @ppdu_id: PPDU unique identifier
|
||||
* @tlv_type: TLV type received
|
||||
*
|
||||
* return: ppdu_info per ppdu tlv structure
|
||||
*/
|
||||
static
|
||||
struct ppdu_info *dp_get_ppdu_desc(struct dp_pdev *pdev, uint32_t ppdu_id,
|
||||
uint8_t tlv_type)
|
||||
{
|
||||
struct ppdu_info *ppdu_info = NULL;
|
||||
|
||||
/*
|
||||
* Find ppdu_id node exists or not
|
||||
*/
|
||||
TAILQ_FOREACH(ppdu_info, &pdev->ppdu_info_list, ppdu_info_list_elem) {
|
||||
|
||||
if (ppdu_info && (ppdu_info->ppdu_id == ppdu_id)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ppdu_info) {
|
||||
/**
|
||||
* if we get tlv_type that is already been processed for ppdu,
|
||||
* that means we got a new ppdu with same ppdu id.
|
||||
* Hence Flush the older ppdu
|
||||
*/
|
||||
if (ppdu_info->tlv_bitmap & (1 << tlv_type))
|
||||
dp_ppdu_desc_deliver(pdev, ppdu_info);
|
||||
else
|
||||
return ppdu_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush the head ppdu descriptor if ppdu desc list reaches max
|
||||
* threshold
|
||||
*/
|
||||
if (pdev->list_depth > HTT_PPDU_DESC_MAX_DEPTH) {
|
||||
ppdu_info = TAILQ_FIRST(&pdev->ppdu_info_list);
|
||||
dp_ppdu_desc_deliver(pdev, ppdu_info);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate new ppdu_info node
|
||||
*/
|
||||
ppdu_info = qdf_mem_malloc(sizeof(struct ppdu_info));
|
||||
if (!ppdu_info)
|
||||
return NULL;
|
||||
|
||||
ppdu_info->nbuf = qdf_nbuf_alloc(pdev->soc->osdev,
|
||||
sizeof(struct cdp_tx_completion_ppdu), 0, 4,
|
||||
TRUE);
|
||||
if (!ppdu_info->nbuf) {
|
||||
qdf_mem_free(ppdu_info);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
qdf_mem_zero(qdf_nbuf_data(ppdu_info->nbuf),
|
||||
sizeof(struct cdp_tx_completion_ppdu));
|
||||
|
||||
if (qdf_nbuf_put_tail(ppdu_info->nbuf,
|
||||
sizeof(struct cdp_tx_completion_ppdu)) == NULL) {
|
||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||
"No tailroom for HTT PPDU");
|
||||
qdf_nbuf_free(ppdu_info->nbuf);
|
||||
ppdu_info->nbuf = NULL;
|
||||
ppdu_info->last_user = 0;
|
||||
qdf_mem_free(ppdu_info);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* No lock is needed because all PPDU TLVs are processed in
|
||||
* same context and this list is updated in same context
|
||||
*/
|
||||
TAILQ_INSERT_TAIL(&pdev->ppdu_info_list, ppdu_info,
|
||||
ppdu_info_list_elem);
|
||||
pdev->list_depth++;
|
||||
return ppdu_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_htt_process_tlv(): Function to process each PPDU TLVs
|
||||
* @pdev: DP pdev handle
|
||||
* @htt_t2h_msg: HTT target to host message
|
||||
*
|
||||
* return: ppdu_info per ppdu tlv structure
|
||||
*/
|
||||
|
||||
static struct ppdu_info *dp_htt_process_tlv(struct dp_pdev *pdev,
|
||||
qdf_nbuf_t htt_t2h_msg)
|
||||
{
|
||||
uint32_t length;
|
||||
uint32_t ppdu_id;
|
||||
uint8_t tlv_type;
|
||||
uint32_t tlv_length;
|
||||
uint32_t tlv_length, tlv_bitmap_expected;
|
||||
uint8_t *tlv_buf;
|
||||
QDF_STATUS status = QDF_STATUS_E_PENDING;
|
||||
struct ppdu_info *ppdu_info = NULL;
|
||||
|
||||
uint32_t *msg_word = (uint32_t *) qdf_nbuf_data(htt_t2h_msg);
|
||||
|
||||
|
|
@ -2263,6 +2484,7 @@ static QDF_STATUS 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;
|
||||
|
|
@ -2274,22 +2496,56 @@ static QDF_STATUS dp_htt_process_tlv(struct dp_pdev *pdev,
|
|||
if (tlv_length == 0)
|
||||
break;
|
||||
|
||||
if (tlv_type == HTT_PPDU_STATS_SCH_CMD_STATUS_TLV)
|
||||
status = QDF_STATUS_SUCCESS;
|
||||
|
||||
if ((tlv_type == HTT_PPDU_STATS_USR_COMPLTN_ACK_BA_STATUS_TLV) &&
|
||||
(pdev->last_ppdu_id != ppdu_id))
|
||||
status = QDF_STATUS_SUCCESS;
|
||||
|
||||
tlv_length += HTT_TLV_HDR_LEN;
|
||||
dp_process_ppdu_tag(pdev, msg_word, tlv_length);
|
||||
|
||||
/**
|
||||
* Not allocating separate ppdu descriptor for MGMT Payload
|
||||
* TLV as this is sent as separate WDI indication and it
|
||||
* doesn't contain any ppdu information
|
||||
*/
|
||||
if (tlv_type == HTT_PPDU_STATS_TX_MGMTCTRL_PAYLOAD_TLV) {
|
||||
dp_process_ppdu_tag(pdev, msg_word, tlv_length, NULL);
|
||||
msg_word = (uint32_t *)((uint8_t *)tlv_buf + tlv_length);
|
||||
length -= (tlv_length);
|
||||
continue;
|
||||
}
|
||||
|
||||
ppdu_info = dp_get_ppdu_desc(pdev, ppdu_id, tlv_type);
|
||||
if (!ppdu_info)
|
||||
return NULL;
|
||||
ppdu_info->ppdu_id = ppdu_id;
|
||||
ppdu_info->tlv_bitmap |= (1 << tlv_type);
|
||||
|
||||
dp_process_ppdu_tag(pdev, msg_word, tlv_length, ppdu_info);
|
||||
|
||||
/**
|
||||
* Increment pdev level tlv count to monitor
|
||||
* missing TLVs
|
||||
*/
|
||||
pdev->tlv_count++;
|
||||
ppdu_info->last_tlv_cnt = pdev->tlv_count;
|
||||
|
||||
msg_word = (uint32_t *)((uint8_t *)tlv_buf + tlv_length);
|
||||
length -= (tlv_length);
|
||||
}
|
||||
|
||||
pdev->last_ppdu_id = ppdu_id;
|
||||
return status;
|
||||
|
||||
tlv_bitmap_expected = HTT_PPDU_DEFAULT_TLV_BITMAP;
|
||||
|
||||
if (pdev->tx_sniffer_enable || pdev->mcopy_mode) {
|
||||
if (ppdu_info->is_ampdu)
|
||||
tlv_bitmap_expected = HTT_PPDU_SNIFFER_AMPDU_TLV_BITMAP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Once all the TLVs for a given PPDU has been processed,
|
||||
* return PPDU status to be delivered to higher layer
|
||||
*/
|
||||
if (ppdu_info->tlv_bitmap == tlv_bitmap_expected)
|
||||
return ppdu_info;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif /* FEATURE_PERPKT_INFO */
|
||||
|
||||
|
|
@ -2307,78 +2563,15 @@ static void dp_txrx_ppdu_stats_handler(struct dp_soc *soc,
|
|||
uint8_t pdev_id, qdf_nbuf_t htt_t2h_msg)
|
||||
{
|
||||
struct dp_pdev *pdev = soc->pdev_list[pdev_id];
|
||||
struct dp_peer *peer;
|
||||
struct cdp_tx_completion_ppdu *ppdu_desc;
|
||||
int status;
|
||||
int i;
|
||||
struct ppdu_info *ppdu_info = NULL;
|
||||
|
||||
if (!pdev->enhanced_stats_en && !pdev->tx_sniffer_enable &&
|
||||
!pdev->mcopy_mode)
|
||||
return;
|
||||
|
||||
if (!pdev->tx_ppdu_info.buf) {
|
||||
/*
|
||||
* Todo: For MU/OFDMA, we need to account for multiple user
|
||||
* descriptors in a PPDU, in skb size.
|
||||
* The allocation has to be moved to ppdu_cmn tlv processing
|
||||
*/
|
||||
pdev->tx_ppdu_info.buf = qdf_nbuf_alloc(soc->osdev,
|
||||
sizeof(struct cdp_tx_completion_ppdu), 0, 4,
|
||||
TRUE);
|
||||
|
||||
if (!pdev->tx_ppdu_info.buf) {
|
||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||
"Nbuf Allocation failed for HTT PPDU");
|
||||
return;
|
||||
}
|
||||
|
||||
qdf_mem_zero(qdf_nbuf_data(pdev->tx_ppdu_info.buf),
|
||||
sizeof(struct cdp_tx_completion_ppdu));
|
||||
|
||||
if (qdf_nbuf_put_tail(pdev->tx_ppdu_info.buf,
|
||||
sizeof(struct cdp_tx_completion_ppdu)) == NULL) {
|
||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||
"No tailroom for HTT PPDU");
|
||||
qdf_nbuf_free(pdev->tx_ppdu_info.buf);
|
||||
pdev->tx_ppdu_info.buf = NULL;
|
||||
pdev->tx_ppdu_info.last_user = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
status = dp_htt_process_tlv(pdev, htt_t2h_msg);
|
||||
|
||||
if (status == QDF_STATUS_SUCCESS) {
|
||||
ppdu_desc = (struct cdp_tx_completion_ppdu *)
|
||||
qdf_nbuf_data(pdev->tx_ppdu_info.buf);
|
||||
|
||||
ppdu_desc->num_users = pdev->tx_ppdu_info.last_user;
|
||||
|
||||
for (i = 0; i < ppdu_desc->num_users; i++) {
|
||||
peer = dp_peer_find_by_id(soc,
|
||||
ppdu_desc->user[i].peer_id);
|
||||
if (!peer)
|
||||
continue;
|
||||
|
||||
ppdu_desc->num_mpdu += ppdu_desc->user[i].num_mpdu;
|
||||
ppdu_desc->num_msdu += ppdu_desc->user[i].num_msdu;
|
||||
|
||||
if (ppdu_desc->user[i].tid < CDP_DATA_TID_MAX) {
|
||||
dp_tx_stats_update(soc, peer,
|
||||
&ppdu_desc->user[i],
|
||||
ppdu_desc->ack_rssi);
|
||||
}
|
||||
}
|
||||
|
||||
dp_wdi_event_handler(WDI_EVENT_TX_PPDU_DESC, soc,
|
||||
pdev->tx_ppdu_info.buf, HTT_INVALID_PEER,
|
||||
WDI_NO_VAL, pdev_id);
|
||||
|
||||
pdev->tx_ppdu_info.buf = NULL;
|
||||
pdev->tx_ppdu_info.last_user = 0;
|
||||
}
|
||||
|
||||
ppdu_info = dp_htt_process_tlv(pdev, htt_t2h_msg);
|
||||
if (ppdu_info)
|
||||
dp_ppdu_desc_deliver(pdev, ppdu_info);
|
||||
}
|
||||
#else
|
||||
static void dp_txrx_ppdu_stats_handler(struct dp_soc *soc,
|
||||
|
|
|
|||
|
|
@ -2614,6 +2614,13 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc,
|
|||
/* set the reo destination during initialization */
|
||||
pdev->reo_dest = pdev->pdev_id + 1;
|
||||
|
||||
/*
|
||||
* initialize ppdu tlv list
|
||||
*/
|
||||
TAILQ_INIT(&pdev->ppdu_info_list);
|
||||
pdev->tlv_count = 0;
|
||||
pdev->list_depth = 0;
|
||||
|
||||
return (struct cdp_pdev *)pdev;
|
||||
|
||||
fail1:
|
||||
|
|
|
|||
|
|
@ -938,6 +938,29 @@ struct dp_neighbour_peer {
|
|||
TAILQ_ENTRY(dp_neighbour_peer) neighbour_peer_list_elem;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ppdu_info - PPDU Status info descriptor
|
||||
* @ppdu_id - Unique ppduid assigned by firmware for every tx packet
|
||||
* @max_ppdu_id - wrap around for ppdu id
|
||||
* @last_tlv_cnt - Keep track for missing ppdu tlvs
|
||||
* @last_user - last ppdu processed for user
|
||||
* @is_ampdu - set if Ampdu aggregate
|
||||
* @nbuf - ppdu descriptor payload
|
||||
* @ppdu_desc - ppdu descriptor
|
||||
* @ppdu_info_list_elem - linked list of ppdu tlvs
|
||||
*/
|
||||
struct ppdu_info {
|
||||
uint32_t ppdu_id;
|
||||
uint32_t max_ppdu_id;
|
||||
uint16_t tlv_bitmap;
|
||||
uint16_t last_tlv_cnt;
|
||||
uint16_t last_user:8,
|
||||
is_ampdu:1;
|
||||
qdf_nbuf_t nbuf;
|
||||
struct cdp_tx_completion_ppdu *ppdu_desc;
|
||||
TAILQ_ENTRY(ppdu_info) ppdu_info_list_elem;
|
||||
};
|
||||
|
||||
/* PDEV level structure for data path */
|
||||
struct dp_pdev {
|
||||
/* PDEV handle from OSIF layer TBD: see if we really need osif_pdev */
|
||||
|
|
@ -1133,6 +1156,10 @@ struct dp_pdev {
|
|||
#ifdef ATH_SUPPORT_NAC_RSSI
|
||||
bool nac_rssi_filtering;
|
||||
#endif
|
||||
/* list of ppdu tlvs */
|
||||
TAILQ_HEAD(, ppdu_info) ppdu_info_list;
|
||||
uint32_t tlv_count;
|
||||
uint32_t list_depth;
|
||||
};
|
||||
|
||||
struct dp_peer;
|
||||
|
|
|
|||
Loading…
Reference in a new issue