summaryrefslogtreecommitdiff
path: root/qcwcn
diff options
context:
space:
mode:
authorAjit Vaishya <ajitv@codeaurora.org>2019-02-26 18:57:43 +0530
committerAhmed ElArabawy <arabawy@google.com>2019-03-12 13:39:39 -0700
commitdbac4bd447d0bc8323a1fec31406475036072095 (patch)
tree2f3a56db8fbf305bcb6deea9f3aaca308ab443df /qcwcn
parent181078ab828d12786c457037cda2fa61a50ab188 (diff)
downloadwlan-dbac4bd447d0bc8323a1fec31406475036072095.tar.gz
Wifi-hal: RX and Per packet fate stats for new pkt log version V2
Current Rx stats parsing structure which is different from new packet log version i.e V2, so parsed RX per packet stats are coming in improper format and per packet fate stats format also is diff w.r.t V2 pkt log version, which leads to improper offset on received payload while parsing it. This commit introduces to parse pktlog stats based on PKT_LOG_V2 parsing structure and V2 based rx rate calculatio. Bug: 118484168 Test: Regression Test Change-Id: Id0997296e93be15158cb9fd27b25067010227666 CRs-Fixed: 2402099
Diffstat (limited to 'qcwcn')
-rw-r--r--qcwcn/wifi_hal/pkt_stats.h41
-rw-r--r--qcwcn/wifi_hal/wifilogger_diag.cpp184
2 files changed, 224 insertions, 1 deletions
diff --git a/qcwcn/wifi_hal/pkt_stats.h b/qcwcn/wifi_hal/pkt_stats.h
index 88a58c0..7cc64b8 100644
--- a/qcwcn/wifi_hal/pkt_stats.h
+++ b/qcwcn/wifi_hal/pkt_stats.h
@@ -186,6 +186,24 @@ struct rx_mpdu_end {
u32 fcs_err : 1; //[31]
} __attribute__((packed));
+/* structure implemented w.r.t PKT_LOG_V2 Version */
+struct rx_msdu_start_v1 {
+ u32 reserved1[2];
+ u32 reserved2 : 8; //[7:0]
+ u32 decap_format : 2; //[9:8]
+ u32 reserved3 : 22; //[31:10]
+ u32 reserved4[2];
+} __attribute__((packed));
+
+struct rx_msdu_end_v1 {
+ u32 reserved1[4];
+ u32 reserved2 : 15; //[14:0]
+ u32 last_msdu : 1; //[15]
+ u32 reserved3 : 16; //[31:16]
+ u32 reserved4[9];
+} __attribute__((packed));
+/************************************************************/
+
#define PREAMBLE_L_SIG_RATE 0x04
#define PREAMBLE_VHT_SIG_A_1 0x08
#define PREAMBLE_VHT_SIG_A_2 0x0c
@@ -223,9 +241,18 @@ struct rx_ppdu_end {
u32 reserved2[5];
} __attribute__((packed));
+struct rx_ppdu_end_V1 {
+ u32 reserved1[18];
+ u32 wb_timestamp_lower_32;
+ u32 reserved2[18];
+} __attribute__((packed));
+
#define MAX_MSDUS_PER_MPDU 3
#define MAX_RXMPDUS_PER_AMPDU 64
#define RX_HTT_HDR_STATUS_LEN 64
+/* RX Data length is 256 for PKT_LOG_V2 Version */
+#define RX_HTT_HDR_STATUS_LEN_V1 256
+
typedef struct {
struct rx_attention attention;
u32 reserved1;
@@ -238,6 +265,20 @@ typedef struct {
char rx_hdr_status[RX_HTT_HDR_STATUS_LEN];
}__attribute__((packed)) rb_pkt_stats_t;
+/* structure implemented w.r.t PKT_LOG_V2 Version */
+typedef struct {
+ struct rx_attention attention;
+ u32 reserved1[2];
+ struct rx_mpdu_start mpdu_start;
+ struct rx_msdu_start_v1 msdu_start;
+ struct rx_msdu_end_v1 msdu_end;
+ struct rx_mpdu_end mpdu_end;
+ struct rx_ppdu_start ppdu_start;
+ struct rx_ppdu_end_V1 ppdu_end;
+ char rx_hdr_status[RX_HTT_HDR_STATUS_LEN_V1];
+}__attribute__((packed)) rb_pkt_stats_t_v1;
+/************************************************************/
+
/*Tx stats specific structures. */
struct ppdu_status {
u32 ba_start_seq_num : 12; //[11:0]
diff --git a/qcwcn/wifi_hal/wifilogger_diag.cpp b/qcwcn/wifi_hal/wifilogger_diag.cpp
index 3714c54..91545db 100644
--- a/qcwcn/wifi_hal/wifilogger_diag.cpp
+++ b/qcwcn/wifi_hal/wifilogger_diag.cpp
@@ -1321,6 +1321,38 @@ static wifi_error update_stats_to_ring_buf(hal_info *info,
return WIFI_SUCCESS;
}
+static u8 cck_ratecode_mapping(u8 rate)
+{
+ u8 rate_code = 0;
+
+ switch (rate) {
+ case 0x1:
+ rate_code = 0x3;
+ break;
+ case 0x2:
+ case 0x5:
+ rate_code = 0x2;
+ break;
+ case 0x3:
+ case 0x6:
+ rate_code = 0x1;
+ break;
+ case 0x4:
+ case 0x7:
+ rate_code = 0x0;
+ break;
+ }
+ return rate_code;
+}
+
+static u8 ofdm_ratecode_mapping(u8 rate)
+{
+ u8 rate_code = 0;
+
+ rate_code = rate - 8;
+ return rate_code;
+}
+
static u16 get_rate_v1(u16 mcs_r)
{
MCS mcs;
@@ -1506,6 +1538,136 @@ static wifi_error populate_rx_aggr_stats(hal_info *info)
return WIFI_SUCCESS;
}
+static wifi_error parse_rx_stats_v2(hal_info *info, u8 *buf, u16 size)
+{
+ wifi_error status = WIFI_SUCCESS;
+ rb_pkt_stats_t_v1 *rx_stats_rcvd = (rb_pkt_stats_t_v1 *)buf;
+ wifi_ring_buffer_entry *pRingBufferEntry;
+ u32 len_ring_buffer_entry = 0;
+
+ if (size < sizeof(rb_pkt_stats_t)) {
+ ALOGE("%s Unexpected rx stats event length: %d", __FUNCTION__, size);
+ memset(info->rx_aggr_pkts, 0, info->rx_buf_size_occupied);
+ memset(&info->aggr_stats, 0, sizeof(rx_aggr_stats));
+ info->rx_buf_size_occupied = 0;
+ return WIFI_ERROR_UNKNOWN;
+ }
+
+ len_ring_buffer_entry = sizeof(wifi_ring_buffer_entry)
+ + sizeof(wifi_ring_per_packet_status_entry)
+ + RX_HTT_HDR_STATUS_LEN_V1;
+
+ if (len_ring_buffer_entry + info->rx_buf_size_occupied
+ > info->rx_buf_size_allocated) {
+ wifi_ring_buffer_entry *temp;
+ temp = (wifi_ring_buffer_entry *)realloc(info->rx_aggr_pkts,
+ len_ring_buffer_entry + info->rx_buf_size_occupied);
+ if (temp == NULL) {
+ ALOGE("%s: Failed to reallocate memory", __FUNCTION__);
+ free(info->rx_aggr_pkts);
+ info->rx_aggr_pkts = NULL;
+ return WIFI_ERROR_OUT_OF_MEMORY;
+ }
+ info->rx_aggr_pkts = temp;
+ memset((u8 *)info->rx_aggr_pkts + info->rx_buf_size_allocated, 0,
+ len_ring_buffer_entry + info->rx_buf_size_occupied
+ - info->rx_buf_size_allocated);
+ info->rx_buf_size_allocated =
+ len_ring_buffer_entry + info->rx_buf_size_occupied;
+ }
+
+ pRingBufferEntry = (wifi_ring_buffer_entry *)((u8 *)info->rx_aggr_pkts
+ + info->rx_buf_size_occupied);
+
+ info->rx_buf_size_occupied += len_ring_buffer_entry;
+
+ /* Fill size of the entry in rb entry which can be used while populating
+ * the data. Actual size that needs to be sent to ring buffer is only pps
+ * entry size
+ */
+ pRingBufferEntry->entry_size = len_ring_buffer_entry;
+ wifi_ring_per_packet_status_entry *rb_pkt_stats =
+ (wifi_ring_per_packet_status_entry *)(pRingBufferEntry + 1);
+
+ memset(rb_pkt_stats, 0, sizeof(wifi_ring_per_packet_status_entry));
+
+ /* Peer tx packet and it is an Rx packet for us */
+ rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_DIRECTION_TX;
+
+ if (!((rx_stats_rcvd->mpdu_end.overflow_err) ||
+ (rx_stats_rcvd->attention.fcs_err) ||
+ (rx_stats_rcvd->attention.mpdu_length_err) ||
+ (rx_stats_rcvd->attention.msdu_length_err) ||
+ (rx_stats_rcvd->attention.tkip_mic_err) ||
+ (rx_stats_rcvd->attention.decrypt_err)))
+ rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_TX_SUCCESS;
+
+ rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_80211_HEADER;
+
+ if (rx_stats_rcvd->mpdu_start.encrypted)
+ rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_PROTECTED;
+
+ if (rx_stats_rcvd->attention.first_mpdu) {
+ MCS *mcs = &info->aggr_stats.RxMCS;
+ u32 ht_vht_sig;
+
+ /* Flush the cached stats as this is the first MPDU. */
+ memset(&info->aggr_stats, 0, sizeof(rx_aggr_stats));
+ if (rx_stats_rcvd->ppdu_start.preamble_type == PREAMBLE_L_SIG_RATE) {
+ if (rx_stats_rcvd->ppdu_start.l_sig_rate_select) {
+ mcs->mcs_s.preamble = WIFI_HW_RATECODE_PREAM_CCK;
+ mcs->mcs_s.rate = cck_ratecode_mapping(rx_stats_rcvd->ppdu_start.l_sig_rate);
+ } else {
+ mcs->mcs_s.preamble = WIFI_HW_RATECODE_PREAM_OFDM;
+ mcs->mcs_s.rate = ofdm_ratecode_mapping(rx_stats_rcvd->ppdu_start.l_sig_rate);
+ }
+ /*BW is 0 for legacy cases*/
+ } else if (rx_stats_rcvd->ppdu_start.preamble_type ==
+ PREAMBLE_VHT_SIG_A_1) {
+ ht_vht_sig = rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_1;
+ mcs->mcs_s.nss = ((ht_vht_sig >> 3) & 0x3);
+ //mcs->mcs_s.nss = (ht_vht_sig & BITMASK(7)) >> 3;
+ mcs->mcs_s.preamble = WIFI_HW_RATECODE_PREAM_HT;
+ mcs->mcs_s.rate = ((ht_vht_sig & BITMASK(7)) % 8) & 0xF;
+ mcs->mcs_s.bw = ((ht_vht_sig >> 7) & 1);
+ mcs->mcs_s.short_gi =
+ ((rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_2 >> 7) & 1);
+ } else if (rx_stats_rcvd->ppdu_start.preamble_type ==
+ PREAMBLE_VHT_SIG_A_2) {
+ ht_vht_sig = rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_1;
+ mcs->mcs_s.nss = ((ht_vht_sig >> 10) & 0x3);
+ mcs->mcs_s.preamble = WIFI_HW_RATECODE_PREAM_VHT;
+ mcs->mcs_s.rate =
+ (rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_2 >> 4) & BITMASK(4);
+ mcs->mcs_s.bw = (ht_vht_sig & 3);
+ mcs->mcs_s.short_gi =
+ (rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_2 & 1);
+ }
+
+ info->aggr_stats.last_transmit_rate
+ = get_rate_v1(info->aggr_stats.RxMCS.mcs);
+
+ info->aggr_stats.rssi = rx_stats_rcvd->ppdu_start.rssi_comb;
+ info->aggr_stats.tid = rx_stats_rcvd->mpdu_start.tid;
+ }
+ rb_pkt_stats->link_layer_transmit_sequence
+ = rx_stats_rcvd->mpdu_start.seq_num;
+
+ memcpy(&rb_pkt_stats->data[0], &rx_stats_rcvd->rx_hdr_status[0],
+ RX_HTT_HDR_STATUS_LEN_V1);
+
+ if ((rx_stats_rcvd->attention.last_mpdu
+ && rx_stats_rcvd->msdu_end.last_msdu)
+ || (rx_stats_rcvd->attention.first_mpdu
+ && rx_stats_rcvd->attention.last_mpdu)) {
+ info->aggr_stats.timestamp = rx_stats_rcvd->ppdu_end.wb_timestamp_lower_32;
+
+ status = populate_rx_aggr_stats(info);
+ }
+
+ return status;
+}
+
static wifi_error parse_rx_stats(hal_info *info, u8 *buf, u16 size)
{
wifi_error status = WIFI_SUCCESS;
@@ -2230,7 +2392,27 @@ static wifi_error parse_stats_record_v2(hal_info *info,
{
wifi_error status = WIFI_SUCCESS;
- if (pkt_stats_header->log_type == PKTLOG_TYPE_PKT_SW_EVENT) {
+ if (pkt_stats_header->log_type == PKTLOG_TYPE_RX_STAT) {
+ /* Ignore the event if it doesn't carry RX descriptor */
+ if (pkt_stats_header->flags & PKT_INFO_FLG_RX_RXDESC_MASK)
+ status = parse_rx_stats_v2(info,
+ (u8 *)(pkt_stats_header + 1),
+ pkt_stats_header->size);
+ else
+ status = WIFI_SUCCESS;
+ } else if (pkt_stats_header->log_type == PKTLOG_TYPE_PKT_DUMP_V2) {
+ pthread_mutex_lock(&info->pkt_fate_stats_lock);
+ if (info->fate_monitoring_enabled) {
+ if (pkt_stats_header->flags & PKT_INFO_FLG_PKT_DUMP_V2)
+ status = parse_pkt_fate_stats(info,
+ (u8 *)pkt_stats_header + sizeof(wh_pktlog_hdr_v2_t),
+ pkt_stats_header->size);
+ else
+ status = WIFI_SUCCESS;
+ } else
+ status = WIFI_SUCCESS;
+ pthread_mutex_unlock(&info->pkt_fate_stats_lock);
+ } else 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);