summaryrefslogtreecommitdiff
path: root/qcwcn/wifi_hal/wifilogger_diag.cpp
diff options
context:
space:
mode:
authorSrinivas Girigowda <quic_sgirigow@quicinc.com>2019-03-28 16:37:13 -0700
committerSunil Ravi <sunilravi@google.com>2019-04-02 21:08:41 +0000
commitd9e4d7c698fda8db6f2532f370185eaeac3ca910 (patch)
treede3a73d4e08f71626f636dbe6786a310f56f543b /qcwcn/wifi_hal/wifilogger_diag.cpp
parent275cf8ba9ecf957cc18c302c3555ddeb43b66c75 (diff)
downloadwlan-d9e4d7c698fda8db6f2532f370185eaeac3ca910.tar.gz
Revert "Revert "Wifi-hal: TX Per Packet stats for V2 version.""
This reverts commit 41d7798f68a93664a836c8b86c23addd3db9d17f. Bug: 129272032 Bug: 118484168 Test: Connect STA to AP and play youtube. Change-Id: If86b053c4e083cf1c01e7d7293d79706c6bb093e
Diffstat (limited to 'qcwcn/wifi_hal/wifilogger_diag.cpp')
-rw-r--r--qcwcn/wifi_hal/wifilogger_diag.cpp264
1 files changed, 254 insertions, 10 deletions
diff --git a/qcwcn/wifi_hal/wifilogger_diag.cpp b/qcwcn/wifi_hal/wifilogger_diag.cpp
index 34d8549..3714c54 100644
--- a/qcwcn/wifi_hal/wifilogger_diag.cpp
+++ b/qcwcn/wifi_hal/wifilogger_diag.cpp
@@ -1321,6 +1321,85 @@ static wifi_error update_stats_to_ring_buf(hal_info *info,
return WIFI_SUCCESS;
}
+static u16 get_rate_v1(u16 mcs_r)
+{
+ MCS mcs;
+ int index = 0;
+ u16 tx_rate = 0;
+ u8 nss;
+
+ mcs.mcs = mcs_r;
+ nss = mcs.mcs_s.nss + 1;
+
+ switch (mcs.mcs_s.preamble) {
+ case WIFI_HW_RATECODE_PREAM_OFDM:
+ for (index = 0; index < MAX_OFDM_MCS_IDX; index++) {
+ if ((mcs.mcs_s.rate & 0xF) == index)
+ tx_rate = (u16) ofdm_mcs_nss1[index].ofdm_rate[mcs.mcs_s.short_gi] / 1000;
+ }
+ break;
+ case WIFI_HW_RATECODE_PREAM_CCK:
+ for (index = 0; index < MAX_CCK_MCS_IDX; index++) {
+ if ((mcs.mcs_s.rate & 0xF) == index)
+ tx_rate = (u16) cck_mcs_nss1[index].cck_rate[mcs.mcs_s.short_gi] / 1000;
+ }
+ break;
+ case WIFI_HW_RATECODE_PREAM_HT:
+ if (nss == 1) {
+ for (index = 0; index < MAX_HT_MCS_IDX; index++) {
+ if (mcs.mcs_s.rate == index) {
+ if (mcs.mcs_s.bw == BW_20MHZ)
+ tx_rate = (u16) mcs_nss1[index].ht20_rate[mcs.mcs_s.short_gi] / 10;
+ if (mcs.mcs_s.bw == BW_40MHZ)
+ tx_rate = (u16) mcs_nss1[index].ht40_rate[mcs.mcs_s.short_gi] / 10;
+ }
+ }
+ } else if (nss == 2) {
+ for (index = 0; index < MAX_HT_MCS_IDX; index++) {
+ if (mcs.mcs_s.rate == index) {
+ if (mcs.mcs_s.bw == BW_20MHZ)
+ tx_rate = (u16) mcs_nss2[index].ht20_rate[mcs.mcs_s.short_gi] / 10;
+ if (mcs.mcs_s.bw == BW_40MHZ)
+ tx_rate = (u16) mcs_nss2[index].ht40_rate[mcs.mcs_s.short_gi] / 10;
+ }
+ }
+ } else {
+ ALOGE("Unexpected nss %d", nss);
+ }
+ break;
+ case WIFI_HW_RATECODE_PREAM_VHT:
+ if (nss == 1) {
+ for (index = 0; index < MAX_VHT_MCS_IDX; index++) {
+ if (mcs.mcs_s.rate == index) {
+ if (mcs.mcs_s.bw == BW_20MHZ)
+ tx_rate = (u16) vht_mcs_nss1[index].ht20_rate[mcs.mcs_s.short_gi] / 10;
+ if (mcs.mcs_s.bw == BW_40MHZ)
+ tx_rate = (u16) vht_mcs_nss1[index].ht40_rate[mcs.mcs_s.short_gi] / 10;
+ if (mcs.mcs_s.bw == BW_80MHZ)
+ tx_rate = (u16) vht_mcs_nss1[index].ht40_rate[mcs.mcs_s.short_gi] / 10;
+ }
+ }
+ } else if (nss == 2) {
+ for (index = 0; index < MAX_VHT_MCS_IDX; index++) {
+ if (mcs.mcs_s.rate == index) {
+ if (mcs.mcs_s.bw == BW_20MHZ)
+ tx_rate = (u16) vht_mcs_nss2[index].ht20_rate[mcs.mcs_s.short_gi] / 10;
+ if (mcs.mcs_s.bw == BW_40MHZ)
+ tx_rate = (u16) vht_mcs_nss2[index].ht40_rate[mcs.mcs_s.short_gi] / 10;
+ if (mcs.mcs_s.bw == BW_80MHZ)
+ tx_rate = (u16) vht_mcs_nss2[index].ht40_rate[mcs.mcs_s.short_gi] / 10;
+ }
+ }
+ } else {
+ ALOGE("Unexpected nss %d", nss);
+ }
+ break;
+ default:
+ ALOGE("Unexpected preamble %d", mcs.mcs_s.preamble);
+ }
+ return tx_rate;
+}
+
static u16 get_rate(u16 mcs_r)
{
u16 tx_rate = 0;
@@ -1551,6 +1630,25 @@ static wifi_error parse_rx_stats(hal_info *info, u8 *buf, u16 size)
return status;
}
+static u16 get_tx_mcs_v1(u8 *data)
+{
+ MCS mcs;
+ RATE_CODE rate_code;
+ u16 extended_flags;
+ mcs.mcs = 0;
+
+ rate_code = *((RATE_CODE*)(data + RATE_CODE_OFFSET));
+ extended_flags = *((u16*)(data + EXT_FLAGS_OFFSET));
+
+ mcs.mcs_s.rate = rate_code.rateCode & 0xF;
+ mcs.mcs_s.nss = (rate_code.rateCode >> 4) & 0x3;
+ mcs.mcs_s.preamble = (rate_code.rateCode >> 6) & 0x3;
+ mcs.mcs_s.short_gi = (((extended_flags >> 12) & 0x1) == 1) ? 1 : 0;
+ mcs.mcs_s.bw = (rate_code.flags >> 5) & 0x3;
+
+ return mcs.mcs;
+}
+
static u16 get_tx_mcs(u8 series,
struct tx_ppdu_start *ppdu_start)
{
@@ -2012,8 +2110,135 @@ static wifi_error parse_pkt_fate_stats(hal_info *info, u8 *buf, u16 size)
return WIFI_SUCCESS;
}
+/*
+ * ---------------------------------------------------------------------------------
+ * | pkt log | packet log data contain sub packet log info |
+ * | header |------------------------------------------------------------------|
+ * | | sub pkt log | sub pkt log | sub pkt log | sub pkt log | |
+ * | | header | data | header | data |..... |
+ * |--------------------------------------------------------------------------------
+ */
+static wifi_error parse_stats_sw_event(hal_info *info,
+ wh_pktlog_hdr_v2_t *pkt_stats_header)
+{
+ u32 pkt_stats_len;
+ int num_of_node = 0;
+ u8 *data;
+ u8 *node_pkt_data;
+ wh_pktlog_hdr_v2_t *pkt_stats_node_header;
+ int node_pkt_type,pkt_sub_type,node_pkt_len,i;
+ wifi_error status = WIFI_SUCCESS;
+ node_pkt_stats node_pkt_t;
+ wifi_ring_buffer_entry *pRingBufferEntry =
+ (wifi_ring_buffer_entry *)info->pkt_stats->tx_stats;
+
+ wifi_ring_per_packet_status_entry *rb_pkt_stats =
+ (wifi_ring_per_packet_status_entry *)(pRingBufferEntry + 1);
+
+ pkt_stats_len = pkt_stats_header->size;
+ data = ((u8 *)pkt_stats_header + sizeof(wh_pktlog_hdr_v2_t));
+ num_of_node = (pkt_stats_header->reserved >> 16) & 0xFFFF;
+ pkt_sub_type = pkt_stats_header->reserved & 0xFFFF;
+
+ do {
+ if (pkt_stats_len < sizeof(wh_pktlog_hdr_v2_t)) {
+ status = WIFI_ERROR_INVALID_ARGS;
+ break;
+ }
+ if (pkt_sub_type == 1) {
+ pkt_stats_node_header = (wh_pktlog_hdr_v2_t *)data;
+ if (pkt_stats_node_header) {
+ node_pkt_type = pkt_stats_node_header->log_type;
+ node_pkt_len = pkt_stats_node_header->size;
+ node_pkt_data = ((u8 *)pkt_stats_node_header + sizeof(wh_pktlog_hdr_v2_t));
+ switch (node_pkt_type) {
+ case PKTLOG_TYPE_TX_CTRL:
+ info->pkt_stats->tx_stats_events |= BIT(PKTLOG_TYPE_TX_CTRL);
+ break;
+ case PKTLOG_TYPE_TX_STAT:
+ {
+ memset(rb_pkt_stats, 0, sizeof(wifi_ring_per_packet_status_entry));
+ memset(&node_pkt_t, 0, sizeof(node_pkt_stats));
+ node_pkt_t.frm_ctrl = *((u16*)(node_pkt_data + FRAME_CTRL_OFFSET));
+ if (node_pkt_t.frm_ctrl & BIT(DATA_PROTECTED))
+ rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_PROTECTED;
+ rb_pkt_stats->transmit_success_timestamp =
+ *((u64*)(node_pkt_data + TX_SUCCESS_TMS_OFFSET));
+ rb_pkt_stats->link_layer_transmit_sequence =
+ *((u16*)(node_pkt_data + LINK_LAYER_TX_SQN_OFFSET));
+ node_pkt_t.tx_ok = *((u8*)(node_pkt_data + TX_STATUS_OFFSET));
+ if (node_pkt_t.tx_ok == 0)
+ rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_TX_SUCCESS;
+ rb_pkt_stats->rssi = *((u8*)(node_pkt_data + TX_RSSI_OFFSET));
+ rb_pkt_stats->num_retries = *((u8*)(node_pkt_data + NO_RETRIES_OFFSET));
+ node_pkt_t.qos_ctrl = *((u8*)(node_pkt_data + QOS_CTRL_OFFSET));
+ rb_pkt_stats->tid = node_pkt_t.qos_ctrl & 0xF;
+ rb_pkt_stats->MCS = get_tx_mcs_v1(node_pkt_data);
+ rb_pkt_stats->last_transmit_rate = get_rate_v1(rb_pkt_stats->MCS);
+ node_pkt_t.bmap_failed = *((u64*)(node_pkt_data + BMAP_FAILED_OFFSET));
+ node_pkt_t.bmap_enqueued = *((u64*)(node_pkt_data + BMAP_ENQUEUED_OFFSET));
+
+ info->pkt_stats->tx_stats_events |= BIT(PKTLOG_TYPE_TX_STAT);
+ rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_80211_HEADER;
+ }
+ break;
+ }
+ if (info->pkt_stats->tx_stats_events & BIT(PKTLOG_TYPE_TX_STAT)) {
+ /* if bmap_enqueued is 1 ,Handle non aggregated cases */
+ if (node_pkt_t.bmap_enqueued == 1) {
+ status = update_stats_to_ring_buf(info,
+ (u8 *)pRingBufferEntry,
+ sizeof(wifi_ring_buffer_entry) +
+ sizeof(wifi_ring_per_packet_status_entry));
+ if (status != WIFI_SUCCESS) {
+ ALOGE("Failed to write into the ring buffer : %d", node_pkt_type);
+ }
+ } else {
+ /* if bmap_enqueued is more than 1 ,Handle aggregated cases */
+ for (i = 0; i < MAX_BA_WINDOW_SIZE; i++) {
+ if (((node_pkt_t.bmap_enqueued >> i) & 0x1) == 1) {
+ if (((node_pkt_t.bmap_failed >> i) & 0x1) == 1) {
+ rb_pkt_stats->flags &= ~PER_PACKET_ENTRY_FLAGS_TX_SUCCESS;
+ } else {
+ rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_TX_SUCCESS;
+ }
+ status = update_stats_to_ring_buf(info,
+ (u8 *)pRingBufferEntry,
+ sizeof(wifi_ring_buffer_entry) +
+ sizeof(wifi_ring_per_packet_status_entry));
+ if (status != WIFI_SUCCESS) {
+ ALOGE("Failed to write into the ring buffer : %d", node_pkt_type);
+ break;
+ }
+ rb_pkt_stats->link_layer_transmit_sequence += 1;
+ }
+ }
+ }
+ }
+ }
+ pkt_stats_len = (pkt_stats_len - (sizeof(wh_pktlog_hdr_v2_t) + node_pkt_len));
+ data = (u8*) (data + sizeof(wh_pktlog_hdr_v2_t) + node_pkt_len);
+ info->pkt_stats->tx_stats_events = 0;
+ }
+ } while (pkt_stats_len > 0);
+ return status;
+}
+
+/* Added This function to parse stats based on PKT_LOG_V2 Version */
+static wifi_error parse_stats_record_v2(hal_info *info,
+ wh_pktlog_hdr_v2_t *pkt_stats_header)
+{
+ wifi_error status = WIFI_SUCCESS;
+
+ if (pkt_stats_header->log_type == PKTLOG_TYPE_PKT_SW_EVENT) {
+ status = parse_stats_sw_event(info, pkt_stats_header);
+ } else
+ ALOGE("%s: invalid log_type %d",__FUNCTION__, pkt_stats_header->log_type);
+
+ return status;
+}
-static wifi_error parse_stats_record(hal_info *info,
+static wifi_error parse_stats_record_v1(hal_info *info,
wh_pktlog_hdr_t *pkt_stats_header)
{
wifi_error status;
@@ -2056,6 +2281,7 @@ static wifi_error parse_stats_record(hal_info *info,
static wifi_error parse_stats(hal_info *info, u8 *data, u32 buflen)
{
wh_pktlog_hdr_t *pkt_stats_header;
+ wh_pktlog_hdr_v2_t *pkt_stats_header_t;
wifi_error status = WIFI_SUCCESS;
do {
@@ -2070,18 +2296,36 @@ static wifi_error parse_stats(hal_info *info, u8 *data, u32 buflen)
status = WIFI_ERROR_INVALID_ARGS;
break;
}
- status = parse_stats_record(info, pkt_stats_header);
- if (status != WIFI_SUCCESS) {
- ALOGE("Failed to parse the stats type : %d",
- pkt_stats_header->log_type);
- return status;
+ /* Pkt_log_V2 based packet parsing */
+ if (info->pkt_log_ver == PKT_LOG_V2) {
+ pkt_stats_header_t = (wh_pktlog_hdr_v2_t *)data;
+ status = parse_stats_record_v2(info, pkt_stats_header_t);
+ if (status != WIFI_SUCCESS) {
+ ALOGE("Failed to parse the stats type : %d",
+ pkt_stats_header_t->log_type);
+ return status;
+ }
+ /* Pkt_log_V1 based packet parsing */
+ } else {
+ status = parse_stats_record_v1(info, pkt_stats_header);
+ if (status != WIFI_SUCCESS) {
+ ALOGE("Failed to parse the stats type : %d",
+ pkt_stats_header->log_type);
+ return status;
+ }
}
- if (pkt_stats_header->flags & PKT_INFO_FLG_PKT_DUMP_V2){
+
+ if (info->pkt_log_ver == PKT_LOG_V1) {
+ if (pkt_stats_header->flags & PKT_INFO_FLG_PKT_DUMP_V2){
+ data += (sizeof(wh_pktlog_hdr_v2_t) + pkt_stats_header->size);
+ buflen -= (sizeof(wh_pktlog_hdr_v2_t) + pkt_stats_header->size);
+ } else {
+ data += (sizeof(wh_pktlog_hdr_t) + pkt_stats_header->size);
+ buflen -= (sizeof(wh_pktlog_hdr_t) + pkt_stats_header->size);
+ }
+ } else if (info->pkt_log_ver == PKT_LOG_V2) {
data += (sizeof(wh_pktlog_hdr_v2_t) + pkt_stats_header->size);
buflen -= (sizeof(wh_pktlog_hdr_v2_t) + pkt_stats_header->size);
- } else {
- data += (sizeof(wh_pktlog_hdr_t) + pkt_stats_header->size);
- buflen -= (sizeof(wh_pktlog_hdr_t) + pkt_stats_header->size);
}
} while (buflen > 0);