qcacmn: Add PPDU statistics support for Tx datapath
Add support to process HTT PPDU statistics for transmit datapath and deliver PPDU indication to CDP interface. Change-Id: I22e757497e13ce86fb7b42112fd56555c58e97bc CRs-Fixed: 2098696
This commit is contained in:

committed by
snandini

parent
9b24afb720
commit
038d090817
@@ -42,6 +42,8 @@
|
|||||||
#define OL_TXRX_NUM_LOCAL_PEER_IDS 33 /* default */
|
#define OL_TXRX_NUM_LOCAL_PEER_IDS 33 /* default */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define CDP_BA_256_BIT_MAP_SIZE_DWORDS 256
|
||||||
|
|
||||||
#define OL_TXRX_INVALID_LOCAL_PEER_ID 0xffff
|
#define OL_TXRX_INVALID_LOCAL_PEER_ID 0xffff
|
||||||
#define CDP_INVALID_VDEV_ID 0xff
|
#define CDP_INVALID_VDEV_ID 0xff
|
||||||
/* 1 additional MCS is for invalid values */
|
/* 1 additional MCS is for invalid values */
|
||||||
@@ -436,6 +438,7 @@ typedef void (*ol_txrx_stats_callback)(void *ctxt,
|
|||||||
* configuration, each netbuf may also have a
|
* configuration, each netbuf may also have a
|
||||||
* monitor-mode encapsulation header such as a radiotap
|
* monitor-mode encapsulation header such as a radiotap
|
||||||
* header added before the MPDU contents.
|
* header added before the MPDU contents.
|
||||||
|
* @rx.std - the OS shim rx function to deliver rx data
|
||||||
* @proxy_arp - proxy arp function pointer - specified by
|
* @proxy_arp - proxy arp function pointer - specified by
|
||||||
* OS shim, stored by txrx
|
* OS shim, stored by txrx
|
||||||
* @get_key - function pointer to get key of the peer with
|
* @get_key - function pointer to get key of the peer with
|
||||||
@@ -637,7 +640,6 @@ struct cdp_tx_stats {
|
|||||||
struct cdp_pkt_info tx_success;
|
struct cdp_pkt_info tx_success;
|
||||||
/* Total Tx failure */
|
/* Total Tx failure */
|
||||||
uint32_t tx_failed;
|
uint32_t tx_failed;
|
||||||
|
|
||||||
/* Total Packets as ofdma*/
|
/* Total Packets as ofdma*/
|
||||||
uint32_t ofdma;
|
uint32_t ofdma;
|
||||||
/* Packets in STBC */
|
/* Packets in STBC */
|
||||||
@@ -905,4 +907,254 @@ struct cdp_pdev_stats {
|
|||||||
/* Number of Rx ring descriptors reaped per interrupt */
|
/* Number of Rx ring descriptors reaped per interrupt */
|
||||||
struct cdp_hist_rx_ind rx_ind_histogram;
|
struct cdp_hist_rx_ind rx_ind_histogram;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct cdp_tx_completion_ppdu_user - Tx PPDU completion per-user information
|
||||||
|
* @completion_status: completion status - OK/Filter/Abort/Timeout
|
||||||
|
* @tid: TID number
|
||||||
|
* @peer_id: Peer ID
|
||||||
|
* @frame_ctrl: frame control field in 802.11 header
|
||||||
|
* @qos_ctrl: QoS control field in 802.11 header
|
||||||
|
* @mpdu_tried: number of mpdus tried
|
||||||
|
* @mpdu_success: number of mpdus successfully transmitted
|
||||||
|
* @long_retries: long retries
|
||||||
|
* @short_retries: short retries
|
||||||
|
* @is_ampdu: mpdu aggregate or non-aggregate?
|
||||||
|
* @success_bytes: bytes successfully transmitted
|
||||||
|
* @retry_bytes: bytes retried
|
||||||
|
* @failed_msdus: MSDUs failed transmission
|
||||||
|
* @duration: user duration in ppdu
|
||||||
|
* @ltf_size: ltf_size
|
||||||
|
* @stbc: stbc
|
||||||
|
* @he_re: he_re (range extension)
|
||||||
|
* @txbf: txbf
|
||||||
|
* @bw: Transmission bandwidth
|
||||||
|
* <enum 0 transmit_bw_20_MHz>
|
||||||
|
* <enum 1 transmit_bw_40_MHz>
|
||||||
|
* <enum 2 transmit_bw_80_MHz>
|
||||||
|
* <enum 3 transmit_bw_160_MHz>
|
||||||
|
* @nss: NSS 1,2, ...8
|
||||||
|
* @mcs: MCS index
|
||||||
|
* @preamble: preamble
|
||||||
|
* @gi: guard interval 800/400/1600/3200 ns
|
||||||
|
* @dcm: dcm
|
||||||
|
* @ldpc: ldpc
|
||||||
|
* @ppdu_type: SU/MU_MIMO/MU_OFDMA/MU_MIMO_OFDMA/UL_TRIG/BURST_BCN/UL_BSR_RESP/
|
||||||
|
* UL_BSR_TRIG/UNKNOWN
|
||||||
|
* @ba_seq_no: Block Ack sequence number
|
||||||
|
* @ba_bitmap: Block Ack bitmap
|
||||||
|
* @start_seqa: Sequence number of first MPDU
|
||||||
|
* @enq_bitmap: Enqueue MPDU bitmap
|
||||||
|
*/
|
||||||
|
struct cdp_tx_completion_ppdu_user {
|
||||||
|
uint32_t completion_status:8,
|
||||||
|
tid:8,
|
||||||
|
peer_id:16;
|
||||||
|
uint8_t mac_addr[6];
|
||||||
|
uint32_t frame_ctrl:16,
|
||||||
|
qos_ctrl:16;
|
||||||
|
uint32_t mpdu_tried:16,
|
||||||
|
mpdu_success:16;
|
||||||
|
uint32_t long_retries:4,
|
||||||
|
short_retries:4,
|
||||||
|
tx_ratecode:8,
|
||||||
|
is_ampdu:1;
|
||||||
|
uint32_t success_bytes;
|
||||||
|
uint32_t retry_bytes;
|
||||||
|
uint32_t failed_bytes;
|
||||||
|
uint32_t success_msdus:16,
|
||||||
|
retry_msdus:16;
|
||||||
|
uint32_t failed_msdus:16,
|
||||||
|
duration:16;
|
||||||
|
uint32_t ltf_size:2,
|
||||||
|
stbc:1,
|
||||||
|
he_re:1,
|
||||||
|
txbf:4,
|
||||||
|
bw:4,
|
||||||
|
nss:4,
|
||||||
|
mcs:4,
|
||||||
|
preamble:4,
|
||||||
|
gi:4,
|
||||||
|
dcm:1,
|
||||||
|
ldpc:1,
|
||||||
|
ppdu_type:2;
|
||||||
|
uint32_t ba_seq_no;
|
||||||
|
uint32_t ba_bitmap[CDP_BA_256_BIT_MAP_SIZE_DWORDS];
|
||||||
|
uint32_t start_seq;
|
||||||
|
uint32_t enq_bitmap[CDP_BA_256_BIT_MAP_SIZE_DWORDS];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct cdp_tx_completion_ppdu - Tx PPDU completion information
|
||||||
|
* @completion_status: completion status - OK/Filter/Abort/Timeout
|
||||||
|
* @ppdu_id: PPDU Id
|
||||||
|
* @vdev_id: VAP Id
|
||||||
|
* @num_users: Number of users
|
||||||
|
* @num_mpdu: Number of MPDUs in PPDU
|
||||||
|
* @num_msdu: Number of MSDUs in PPDU
|
||||||
|
* @channel: Channel informartion
|
||||||
|
* @ack_rssi: RSSI value of last ack packet (units=dB above noise floor)
|
||||||
|
* @ppdu_start_timestamp: TSF at PPDU start
|
||||||
|
* @ppdu_end_timestamp: TSF at PPDU end
|
||||||
|
* @ack_timestamp: TSF at the reception of ACK
|
||||||
|
* @user: per-User stats (array of per-user structures)
|
||||||
|
*/
|
||||||
|
struct cdp_tx_completion_ppdu {
|
||||||
|
uint32_t ppdu_id;
|
||||||
|
uint16_t vdev_id;
|
||||||
|
uint32_t num_users;
|
||||||
|
uint32_t num_mpdu:9,
|
||||||
|
num_msdu:16;
|
||||||
|
uint8_t channel;
|
||||||
|
uint32_t ack_rssi;
|
||||||
|
uint32_t ppdu_start_timestamp;
|
||||||
|
uint32_t ppdu_end_timestamp;
|
||||||
|
uint32_t ack_timestamp;
|
||||||
|
struct cdp_tx_completion_ppdu_user user[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct cdp_rate_stats - Tx/Rx Rate statistics
|
||||||
|
* @bw: Indicates the BW of the upcoming transmission -
|
||||||
|
* <enum 0 transmit_bw_20_MHz>
|
||||||
|
* <enum 1 transmit_bw_40_MHz>
|
||||||
|
* <enum 2 transmit_bw_80_MHz>
|
||||||
|
* <enum 3 transmit_bw_160_MHz>
|
||||||
|
* @pkt_type: Transmit Packet Type
|
||||||
|
* @stbc: When set, STBC transmission rate was used
|
||||||
|
* @ldpc: When set, use LDPC transmission rates
|
||||||
|
* @sgi: <enum 0 0_8_us_sgi > Legacy normal GI
|
||||||
|
* <enum 1 0_4_us_sgi > Legacy short GI
|
||||||
|
* <enum 2 1_6_us_sgi > HE related GI
|
||||||
|
* <enum 3 3_2_us_sgi > HE
|
||||||
|
* @mcs: Transmit MCS Rate
|
||||||
|
* @ofdma: Set when the transmission was an OFDMA transmission
|
||||||
|
* @tones_in_ru: The number of tones in the RU used.
|
||||||
|
* @tsf: Lower 32 bits of the TSF (timestamp when ppdu transmission finished)
|
||||||
|
* @peer_id: Peer ID of the flow or MPDU queue
|
||||||
|
* @tid: TID of the flow or MPDU queue
|
||||||
|
*/
|
||||||
|
struct cdp_rate_stats {
|
||||||
|
uint32_t rate_stats_info_valid:1,
|
||||||
|
bw:2,
|
||||||
|
pkt_type:4,
|
||||||
|
stbc:1,
|
||||||
|
ldpc:1,
|
||||||
|
sgi:2,
|
||||||
|
mcs:4,
|
||||||
|
ofdma:1,
|
||||||
|
tones_in_ru:12,
|
||||||
|
resvd0:4;
|
||||||
|
uint32_t tsf;
|
||||||
|
uint16_t peer_id;
|
||||||
|
uint8_t tid;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct cdp_tx_completion_msdu - Tx MSDU completion descriptor
|
||||||
|
* @ppdu_id: PPDU to which this MSDU belongs
|
||||||
|
* @transmit_cnt: Number of times this frame has been transmitted
|
||||||
|
* @ack_frame_rssi: RSSI of the received ACK or BA frame
|
||||||
|
* @first_msdu: Indicates this MSDU is the first MSDU in AMSDU
|
||||||
|
* @last_msdu: Indicates this MSDU is the last MSDU in AMSDU
|
||||||
|
* @msdu_part_of_amsdu : Indicates this MSDU was part of an A-MSDU in MPDU
|
||||||
|
* @extd: Extended structure containing rate statistics
|
||||||
|
*/
|
||||||
|
struct cdp_tx_completion_msdu {
|
||||||
|
uint32_t ppdu_id;
|
||||||
|
uint8_t transmit_cnt;
|
||||||
|
uint32_t ack_frame_rssi:8,
|
||||||
|
resvd0:1,
|
||||||
|
first_msdu:1,
|
||||||
|
last_msdu:1,
|
||||||
|
msdu_part_of_amsdu:1,
|
||||||
|
resvd1:20;
|
||||||
|
struct cdp_rate_stats extd;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct cdp_rx_indication_ppdu - Rx PPDU indication structure
|
||||||
|
* @ppdu_id: PPDU Id
|
||||||
|
* @is_ampdu: mpdu aggregate or non-aggregate?
|
||||||
|
* @num_mpdu: Number of MPDUs in PPDU
|
||||||
|
* @num_msdu: Number of MSDUs in PPDU
|
||||||
|
* @duration: PPDU duration
|
||||||
|
* @tid: TID number
|
||||||
|
* @peer_id: Peer ID
|
||||||
|
* @ltf_size: ltf_size
|
||||||
|
* @stbc: When set, STBC rate was used
|
||||||
|
* @he_re: he_re (range extension)
|
||||||
|
* @bw: Bandwidth
|
||||||
|
* <enum 0 bw_20_MHz>
|
||||||
|
* <enum 1 bw_40_MHz>
|
||||||
|
* <enum 2 bw_80_MHz>
|
||||||
|
* <enum 3 bw_160_MHz>
|
||||||
|
* @nss: NSS 1,2, ...8
|
||||||
|
* @mcs: MCS index
|
||||||
|
* @preamble: preamble
|
||||||
|
* @gi: <enum 0 0_8_us_sgi > Legacy normal GI
|
||||||
|
* <enum 1 0_4_us_sgi > Legacy short GI
|
||||||
|
* <enum 2 1_6_us_sgi > HE related GI
|
||||||
|
* <enum 3 3_2_us_sgi > HE
|
||||||
|
* @dcm: dcm
|
||||||
|
* @ldpc: ldpc
|
||||||
|
* @ppdu_type: SU/MU_MIMO/MU_OFDMA/MU_MIMO_OFDMA/UL_TRIG/BURST_BCN/UL_BSR_RESP/
|
||||||
|
* UL_BSR_TRIG/UNKNOWN
|
||||||
|
* @rssi: RSSI value (units = dB above noise floor)
|
||||||
|
* @timestamp: TSF at the reception of PPDU
|
||||||
|
* @channel: Channel informartion
|
||||||
|
* @lsig_A: L-SIG in 802.11 PHY header
|
||||||
|
*/
|
||||||
|
struct cdp_rx_indication_ppdu {
|
||||||
|
uint32_t ppdu_id;
|
||||||
|
uint32_t is_ampdu:1,
|
||||||
|
num_mpdu:9,
|
||||||
|
num_msdu:16;
|
||||||
|
uint16_t duration;
|
||||||
|
uint32_t tid:8,
|
||||||
|
peer_id:16;
|
||||||
|
union {
|
||||||
|
uint32_t rate_info;
|
||||||
|
struct {
|
||||||
|
uint32_t ltf_size:2,
|
||||||
|
stbc:1,
|
||||||
|
he_re:1,
|
||||||
|
bw:4,
|
||||||
|
nss:4,
|
||||||
|
mcs:4,
|
||||||
|
preamble:4,
|
||||||
|
gi:4,
|
||||||
|
dcm:1,
|
||||||
|
ldpc:1,
|
||||||
|
ppdu_type:2;
|
||||||
|
};
|
||||||
|
} u;
|
||||||
|
uint32_t lsig_a;
|
||||||
|
uint32_t rssi;
|
||||||
|
uint32_t timestamp;
|
||||||
|
uint8_t channel;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct cdp_rx_indication_msdu - Rx MSDU info
|
||||||
|
* @ppdu_id: PPDU to which the MSDU belongs
|
||||||
|
* @msdu_len: Length of MSDU in bytes
|
||||||
|
* @ack_frame_rssi: RSSI of the received ACK or BA frame
|
||||||
|
* @first_msdu: Indicates this MSDU is the first MSDU in AMSDU
|
||||||
|
* @last_msdu: Indicates this MSDU is the last MSDU in AMSDU
|
||||||
|
* @msdu_part_of_amsdu : Indicates this MSDU was part of an A-MSDU in MPDU
|
||||||
|
* @extd: Extended structure containing rate statistics
|
||||||
|
*/
|
||||||
|
struct cdp_rx_indication_msdu {
|
||||||
|
uint32_t ppdu_id;
|
||||||
|
uint16_t msdu_len;
|
||||||
|
uint32_t ack_frame_rssi:8,
|
||||||
|
resvd0:1,
|
||||||
|
first_msdu:1,
|
||||||
|
last_msdu:1,
|
||||||
|
msdu_part_of_amsdu:1,
|
||||||
|
msdu_part_of_ampdu:1,
|
||||||
|
resvd1:19;
|
||||||
|
struct cdp_rate_stats extd;
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@@ -24,7 +24,9 @@
|
|||||||
#include "dp_internal.h"
|
#include "dp_internal.h"
|
||||||
#include "dp_rx_mon.h"
|
#include "dp_rx_mon.h"
|
||||||
#include "htt_stats.h"
|
#include "htt_stats.h"
|
||||||
|
#include "htt_ppdu_stats.h"
|
||||||
#include "qdf_mem.h" /* qdf_mem_malloc,free */
|
#include "qdf_mem.h" /* qdf_mem_malloc,free */
|
||||||
|
#include "cdp_txrx_cmn_struct.h"
|
||||||
|
|
||||||
#define HTT_TLV_HDR_LEN HTT_T2H_EXT_STATS_CONF_TLV_HDR_SIZE
|
#define HTT_TLV_HDR_LEN HTT_T2H_EXT_STATS_CONF_TLV_HDR_SIZE
|
||||||
|
|
||||||
@@ -42,6 +44,47 @@ do { \
|
|||||||
htt_htc_misc_pkt_list_add(soc, pkt); \
|
htt_htc_misc_pkt_list_add(soc, pkt); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dp_tx_stats_update() - Update per-peer statistics
|
||||||
|
* @soc: Datapath soc handle
|
||||||
|
* @peer: Datapath peer handle
|
||||||
|
* @ppdu: PPDU Descriptor
|
||||||
|
* @ack_rssi: RSSI of last ack received
|
||||||
|
*
|
||||||
|
* Return: None
|
||||||
|
*/
|
||||||
|
#ifdef FEATURE_PERPKT_INFO
|
||||||
|
static void dp_tx_stats_update(struct dp_soc *soc, struct dp_peer *peer,
|
||||||
|
struct cdp_tx_completion_ppdu_user *ppdu, uint32_t ack_rssi)
|
||||||
|
{
|
||||||
|
struct dp_pdev *pdev = peer->vdev->pdev;
|
||||||
|
|
||||||
|
DP_STATS_INC_PKT(peer, tx.comp_pkt,
|
||||||
|
(ppdu->success_msdus + ppdu->retry_msdus +
|
||||||
|
ppdu->failed_msdus),
|
||||||
|
ppdu->success_bytes);
|
||||||
|
DP_STATS_INC(peer, tx.tx_failed, ppdu->failed_msdus);
|
||||||
|
DP_STATS_INC(peer,
|
||||||
|
tx.pkt_type[ppdu->preamble].mcs_count[ppdu->mcs], 1);
|
||||||
|
DP_STATS_INC(peer, tx.sgi_count[ppdu->gi], 1);
|
||||||
|
DP_STATS_INC(peer, tx.bw[ppdu->bw], 1);
|
||||||
|
DP_STATS_UPD(peer, tx.last_ack_rssi, ack_rssi);
|
||||||
|
DP_STATS_INC(peer, tx.wme_ac_type[TID_TO_WME_AC(ppdu->tid)], 1);
|
||||||
|
DP_STATS_INC(peer, tx.stbc, ppdu->stbc);
|
||||||
|
DP_STATS_INC(peer, tx.ldpc, ppdu->ldpc);
|
||||||
|
DP_STATS_INC_PKT(peer, tx.tx_success, ppdu->success_msdus,
|
||||||
|
ppdu->success_bytes);
|
||||||
|
DP_STATS_INC(peer, tx.retries,
|
||||||
|
(ppdu->long_retries + ppdu->short_retries));
|
||||||
|
|
||||||
|
if (soc->cdp_soc.ol_ops->update_dp_stats) {
|
||||||
|
soc->cdp_soc.ol_ops->update_dp_stats(pdev->osif_pdev,
|
||||||
|
&peer->stats, ppdu->peer_id,
|
||||||
|
UPDATE_PEER_STATS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* htt_htc_pkt_alloc() - Allocate HTC packet buffer
|
* htt_htc_pkt_alloc() - Allocate HTC packet buffer
|
||||||
* @htt_soc: HTT SOC handle
|
* @htt_soc: HTT SOC handle
|
||||||
@@ -1225,7 +1268,211 @@ void htt_t2h_stats_handler(void *context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dp_txrx_fw_stats_handler():Function to process HTT EXT stats
|
* 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
|
||||||
|
*
|
||||||
|
* return:void
|
||||||
|
*/
|
||||||
|
static void dp_process_ppdu_stats_user_rate_tlv(struct dp_pdev *pdev,
|
||||||
|
uint32_t *tag_buf)
|
||||||
|
{
|
||||||
|
uint32_t peer_id;
|
||||||
|
struct dp_peer *peer;
|
||||||
|
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);
|
||||||
|
|
||||||
|
tag_buf++;
|
||||||
|
peer_id = HTT_PPDU_STATS_USER_RATE_TLV_SW_PEER_ID_GET(*tag_buf);
|
||||||
|
peer = dp_peer_find_by_id(pdev->soc, peer_id);
|
||||||
|
|
||||||
|
if (!peer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ppdu_user_desc = &ppdu_desc->user[pdev->tx_ppdu_info.curr_user];
|
||||||
|
|
||||||
|
ppdu_user_desc->tid =
|
||||||
|
HTT_PPDU_STATS_USER_RATE_TLV_TID_NUM_GET(*tag_buf);
|
||||||
|
|
||||||
|
ppdu_user_desc->peer_id = peer_id;
|
||||||
|
|
||||||
|
qdf_mem_copy(ppdu_user_desc->mac_addr, peer->mac_addr.raw,
|
||||||
|
DP_MAC_ADDR_LEN);
|
||||||
|
|
||||||
|
tag_buf += 5;
|
||||||
|
|
||||||
|
ppdu_user_desc->ltf_size =
|
||||||
|
HTT_PPDU_STATS_USER_RATE_TLV_LTF_SIZE_GET(*tag_buf);
|
||||||
|
ppdu_user_desc->stbc =
|
||||||
|
HTT_PPDU_STATS_USER_RATE_TLV_STBC_GET(*tag_buf);
|
||||||
|
ppdu_user_desc->he_re =
|
||||||
|
HTT_PPDU_STATS_USER_RATE_TLV_HE_RE_GET(*tag_buf);
|
||||||
|
ppdu_user_desc->txbf =
|
||||||
|
HTT_PPDU_STATS_USER_RATE_TLV_TXBF_GET(*tag_buf);
|
||||||
|
ppdu_user_desc->bw =
|
||||||
|
HTT_PPDU_STATS_USER_RATE_TLV_BW_GET(*tag_buf);
|
||||||
|
ppdu_user_desc->nss = HTT_PPDU_STATS_USER_RATE_TLV_NSS_GET(*tag_buf);
|
||||||
|
ppdu_user_desc->mcs = HTT_PPDU_STATS_USER_RATE_TLV_MCS_GET(*tag_buf);
|
||||||
|
ppdu_user_desc->preamble =
|
||||||
|
HTT_PPDU_STATS_USER_RATE_TLV_PREAMBLE_GET(*tag_buf);
|
||||||
|
ppdu_user_desc->gi = HTT_PPDU_STATS_USER_RATE_TLV_GI_GET(*tag_buf);
|
||||||
|
ppdu_user_desc->dcm = HTT_PPDU_STATS_USER_RATE_TLV_DCM_GET(*tag_buf);
|
||||||
|
ppdu_user_desc->ldpc = HTT_PPDU_STATS_USER_RATE_TLV_LDPC_GET(*tag_buf);
|
||||||
|
ppdu_user_desc->ppdu_type =
|
||||||
|
HTT_PPDU_STATS_USER_RATE_TLV_PPDU_TYPE_GET(*tag_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp_process_ppdu_tag(): Function to process the PPDU TLVs
|
||||||
|
* @soc: DP Physical device (radio) handle
|
||||||
|
* @tag_buf: TLV buffer
|
||||||
|
*
|
||||||
|
* return: void
|
||||||
|
*/
|
||||||
|
static void dp_process_ppdu_tag(struct dp_pdev *pdev, uint32_t *tag_buf,
|
||||||
|
uint32_t tlv_len)
|
||||||
|
{
|
||||||
|
uint32_t tlv_type = HTT_STATS_TLV_TAG_GET(*tag_buf);
|
||||||
|
|
||||||
|
switch (tlv_type) {
|
||||||
|
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);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static QDF_STATUS 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;
|
||||||
|
uint8_t *tlv_buf;
|
||||||
|
QDF_STATUS status = QDF_STATUS_E_PENDING;
|
||||||
|
|
||||||
|
uint32_t *msg_word = (uint32_t *) qdf_nbuf_data(htt_t2h_msg);
|
||||||
|
|
||||||
|
length = HTT_T2H_PPDU_STATS_PAYLOAD_SIZE_GET(*msg_word);
|
||||||
|
|
||||||
|
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);
|
||||||
|
tlv_length = HTT_STATS_TLV_LENGTH_GET(*msg_word);
|
||||||
|
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
|
||||||
|
"HTT PPDU Tag %d, Length %d", tlv_type,
|
||||||
|
tlv_length);
|
||||||
|
|
||||||
|
if (tlv_length == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (tlv_type == HTT_PPDU_STATS_SCH_CMD_STATUS_TLV)
|
||||||
|
status = QDF_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
tlv_length += HTT_TLV_HDR_LEN;
|
||||||
|
dp_process_ppdu_tag(pdev, msg_word, tlv_length);
|
||||||
|
|
||||||
|
msg_word = (uint32_t *)((uint8_t *)tlv_buf + tlv_length);
|
||||||
|
length -= (tlv_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp_txrx_ppdu_stats_handler() - Function to process HTT PPDU stats from FW
|
||||||
|
* @soc: DP SOC handle
|
||||||
|
* @pdev_id: pdev id
|
||||||
|
* @htt_t2h_msg: HTT message nbuf
|
||||||
|
*
|
||||||
|
* return:void
|
||||||
|
*/
|
||||||
|
#if defined(CONFIG_WIN) && WDI_EVENT_ENABLE
|
||||||
|
#ifdef FEATURE_PERPKT_INFO
|
||||||
|
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_vdev *vdev;
|
||||||
|
struct dp_peer *peer;
|
||||||
|
struct cdp_tx_completion_ppdu *ppdu_desc;
|
||||||
|
int status;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!pdev->enhanced_stats_en)
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
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);
|
||||||
|
|
||||||
|
vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc,
|
||||||
|
ppdu_desc->vdev_id);
|
||||||
|
|
||||||
|
for (i = 0; i < ppdu_desc->num_users; i++) {
|
||||||
|
peer = dp_peer_find_by_id(soc,
|
||||||
|
ppdu_desc->user[i].peer_id);
|
||||||
|
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.curr_user = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void dp_txrx_ppdu_stats_handler(struct dp_soc *soc,
|
||||||
|
uint8_t pdev_id, qdf_nbuf_t htt_t2h_msg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp_txrx_fw_stats_handler() - Function to process HTT EXT stats
|
||||||
* @soc: DP SOC handle
|
* @soc: DP SOC handle
|
||||||
* @htt_t2h_msg: HTT message nbuf
|
* @htt_t2h_msg: HTT message nbuf
|
||||||
*
|
*
|
||||||
@@ -1386,6 +1633,8 @@ static void dp_htt_t2h_msg_handler(void *context, HTC_PACKET *pkt)
|
|||||||
"received HTT_T2H_MSG_TYPE_PPDU_STATS_IND\n");
|
"received HTT_T2H_MSG_TYPE_PPDU_STATS_IND\n");
|
||||||
pdev_id = HTT_T2H_PPDU_STATS_MAC_ID_GET(*msg_word);
|
pdev_id = HTT_T2H_PPDU_STATS_MAC_ID_GET(*msg_word);
|
||||||
pdev_id = DP_HW2SW_MACID(pdev_id);
|
pdev_id = DP_HW2SW_MACID(pdev_id);
|
||||||
|
dp_txrx_ppdu_stats_handler(soc->dp_soc, pdev_id,
|
||||||
|
htt_t2h_msg);
|
||||||
dp_wdi_event_handler(WDI_EVENT_LITE_T2H, soc->dp_soc,
|
dp_wdi_event_handler(WDI_EVENT_LITE_T2H, soc->dp_soc,
|
||||||
htt_t2h_msg, HTT_INVALID_PEER, WDI_NO_VAL,
|
htt_t2h_msg, HTT_INVALID_PEER, WDI_NO_VAL,
|
||||||
pdev_id);
|
pdev_id);
|
||||||
|
@@ -3638,25 +3638,19 @@ void dp_aggregate_vdev_stats(struct dp_vdev *vdev)
|
|||||||
struct dp_peer *peer = NULL;
|
struct dp_peer *peer = NULL;
|
||||||
struct dp_soc *soc = vdev->pdev->soc;
|
struct dp_soc *soc = vdev->pdev->soc;
|
||||||
int i;
|
int i;
|
||||||
|
uint8_t pream_type;
|
||||||
|
|
||||||
qdf_mem_set(&(vdev->stats.tx), sizeof(vdev->stats.tx), 0x0);
|
qdf_mem_set(&(vdev->stats.tx), sizeof(vdev->stats.tx), 0x0);
|
||||||
qdf_mem_set(&(vdev->stats.rx), sizeof(vdev->stats.rx), 0x0);
|
qdf_mem_set(&(vdev->stats.rx), sizeof(vdev->stats.rx), 0x0);
|
||||||
|
|
||||||
TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) {
|
TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) {
|
||||||
if (!peer)
|
for (pream_type = 0; pream_type < DOT11_MAX; pream_type++) {
|
||||||
return;
|
for (i = 0; i < MAX_MCS; i++) {
|
||||||
|
DP_STATS_AGGR(vdev, peer,
|
||||||
for (i = 0; i < MAX_MCS; i++) {
|
tx.pkt_type[pream_type].mcs_count[i]);
|
||||||
DP_STATS_AGGR(vdev, peer, tx.pkt_type[0].mcs_count[i]);
|
DP_STATS_AGGR(vdev, peer,
|
||||||
DP_STATS_AGGR(vdev, peer, tx.pkt_type[1].mcs_count[i]);
|
rx.pkt_type[pream_type].mcs_count[i]);
|
||||||
DP_STATS_AGGR(vdev, peer, tx.pkt_type[2].mcs_count[i]);
|
}
|
||||||
DP_STATS_AGGR(vdev, peer, tx.pkt_type[3].mcs_count[i]);
|
|
||||||
DP_STATS_AGGR(vdev, peer, tx.pkt_type[4].mcs_count[i]);
|
|
||||||
DP_STATS_AGGR(vdev, peer, rx.pkt_type[0].mcs_count[i]);
|
|
||||||
DP_STATS_AGGR(vdev, peer, rx.pkt_type[1].mcs_count[i]);
|
|
||||||
DP_STATS_AGGR(vdev, peer, rx.pkt_type[2].mcs_count[i]);
|
|
||||||
DP_STATS_AGGR(vdev, peer, rx.pkt_type[3].mcs_count[i]);
|
|
||||||
DP_STATS_AGGR(vdev, peer, rx.pkt_type[4].mcs_count[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < MAX_BW; i++) {
|
for (i = 0; i < MAX_BW; i++) {
|
||||||
@@ -3735,27 +3729,23 @@ static inline void dp_aggregate_pdev_stats(struct dp_pdev *pdev)
|
|||||||
{
|
{
|
||||||
struct dp_vdev *vdev = NULL;
|
struct dp_vdev *vdev = NULL;
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
uint8_t pream_type;
|
||||||
|
|
||||||
qdf_mem_set(&(pdev->stats.tx), sizeof(pdev->stats.tx), 0x0);
|
qdf_mem_set(&(pdev->stats.tx), sizeof(pdev->stats.tx), 0x0);
|
||||||
qdf_mem_set(&(pdev->stats.rx), sizeof(pdev->stats.rx), 0x0);
|
qdf_mem_set(&(pdev->stats.rx), sizeof(pdev->stats.rx), 0x0);
|
||||||
qdf_mem_set(&(pdev->stats.tx_i), sizeof(pdev->stats.tx_i), 0x0);
|
qdf_mem_set(&(pdev->stats.tx_i), sizeof(pdev->stats.tx_i), 0x0);
|
||||||
|
|
||||||
TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
|
TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
|
||||||
if (!vdev)
|
|
||||||
return;
|
|
||||||
dp_aggregate_vdev_stats(vdev);
|
dp_aggregate_vdev_stats(vdev);
|
||||||
|
|
||||||
for (i = 0; i < MAX_MCS; i++) {
|
for (pream_type = 0; pream_type < DOT11_MAX; pream_type++) {
|
||||||
DP_STATS_AGGR(pdev, vdev, tx.pkt_type[0].mcs_count[i]);
|
for (i = 0; i < MAX_MCS; i++) {
|
||||||
DP_STATS_AGGR(pdev, vdev, tx.pkt_type[1].mcs_count[i]);
|
DP_STATS_AGGR(pdev, vdev,
|
||||||
DP_STATS_AGGR(pdev, vdev, tx.pkt_type[2].mcs_count[i]);
|
tx.pkt_type[pream_type].mcs_count[i]);
|
||||||
DP_STATS_AGGR(pdev, vdev, tx.pkt_type[3].mcs_count[i]);
|
DP_STATS_AGGR(pdev, vdev,
|
||||||
DP_STATS_AGGR(pdev, vdev, tx.pkt_type[4].mcs_count[i]);
|
rx.pkt_type[pream_type].mcs_count[i]);
|
||||||
DP_STATS_AGGR(pdev, vdev, rx.pkt_type[0].mcs_count[i]);
|
}
|
||||||
DP_STATS_AGGR(pdev, vdev, rx.pkt_type[1].mcs_count[i]);
|
|
||||||
DP_STATS_AGGR(pdev, vdev, rx.pkt_type[2].mcs_count[i]);
|
|
||||||
DP_STATS_AGGR(pdev, vdev, rx.pkt_type[3].mcs_count[i]);
|
|
||||||
DP_STATS_AGGR(pdev, vdev, rx.pkt_type[4].mcs_count[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < MAX_BW; i++) {
|
for (i = 0; i < MAX_BW; i++) {
|
||||||
|
@@ -79,7 +79,6 @@ static inline struct dp_ast_entry *dp_peer_ast_hash_find(struct dp_soc *soc,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DP_LFR
|
|
||||||
/*
|
/*
|
||||||
* dp_get_vdev_from_soc_vdev_id_wifi3() -
|
* dp_get_vdev_from_soc_vdev_id_wifi3() -
|
||||||
* Returns vdev object given the vdev id
|
* Returns vdev object given the vdev id
|
||||||
@@ -113,5 +112,4 @@ dp_get_vdev_from_soc_vdev_id_wifi3(struct dp_soc *soc,
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#endif /* _DP_PEER_H_ */
|
#endif /* _DP_PEER_H_ */
|
||||||
|
@@ -892,6 +892,7 @@ static void dp_tx_classify_tid(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
|||||||
|
|
||||||
is_mcast = DP_FRAME_IS_MULTICAST(hdr_ptr);
|
is_mcast = DP_FRAME_IS_MULTICAST(hdr_ptr);
|
||||||
ether_type = eh->ether_type;
|
ether_type = eh->ether_type;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if packet is dot3 or eth2 type.
|
* Check if packet is dot3 or eth2 type.
|
||||||
*/
|
*/
|
||||||
@@ -917,6 +918,7 @@ static void dp_tx_classify_tid(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
|||||||
L3datap = hdr_ptr + sizeof(qdf_ethervlan_header_t);
|
L3datap = hdr_ptr + sizeof(qdf_ethervlan_header_t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find priority from IP TOS DSCP field
|
* Find priority from IP TOS DSCP field
|
||||||
*/
|
*/
|
||||||
@@ -2517,7 +2519,7 @@ QDF_STATUS dp_tx_soc_attach(struct dp_soc *soc)
|
|||||||
* only for NPR EMU, should be removed, once NPR platforms
|
* only for NPR EMU, should be removed, once NPR platforms
|
||||||
* are stable.
|
* are stable.
|
||||||
*/
|
*/
|
||||||
soc->process_tx_status = 1;
|
soc->process_tx_status = 0;
|
||||||
|
|
||||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
|
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
|
||||||
"%s HAL Tx init Success\n", __func__);
|
"%s HAL Tx init Success\n", __func__);
|
||||||
|
@@ -1041,6 +1041,11 @@ struct dp_pdev {
|
|||||||
|
|
||||||
/* WDI event handlers */
|
/* WDI event handlers */
|
||||||
struct wdi_event_subscribe_t **wdi_event_list;
|
struct wdi_event_subscribe_t **wdi_event_list;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint8_t curr_user;
|
||||||
|
qdf_nbuf_t buf;
|
||||||
|
} tx_ppdu_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dp_peer;
|
struct dp_peer;
|
||||||
|
Reference in New Issue
Block a user