summaryrefslogtreecommitdiff
path: root/qcwcn
diff options
context:
space:
mode:
authorAjit Vaishya <ajitv@codeaurora.org>2019-02-26 18:25:55 +0530
committerAhmed ElArabawy <arabawy@google.com>2019-03-12 13:38:07 -0700
commit181078ab828d12786c457037cda2fa61a50ab188 (patch)
tree1cfb2baacdcb04518983a3353864247ed83035aa /qcwcn
parent74064d74227d7e64e962c82d79c491578acf714e (diff)
downloadwlan-181078ab828d12786c457037cda2fa61a50ab188.tar.gz
Wifi-hal: TX Per Packet stats for V2 version.
Current TX per packet stats parsing logic cannot be used to parse TX stats for packet log new version V2, because of packet log structre format is different. This changes introduces to parse new packet log version V2, based on required OFFSET from received TX payload. Support to read packet log version i.e V1/V2/V3 by reading firmare version. Bug: 118484168 Test: Regression test Change-Id: Ie5c508bb2fd3e00674dd807c3003b00857d3f070 CRs-Fixed: 2402099
Diffstat (limited to 'qcwcn')
-rw-r--r--qcwcn/wifi_hal/common.h8
-rw-r--r--qcwcn/wifi_hal/pkt_stats.h195
-rw-r--r--qcwcn/wifi_hal/wifi_hal.cpp21
-rw-r--r--qcwcn/wifi_hal/wifilogger.cpp3
-rw-r--r--qcwcn/wifi_hal/wifilogger_diag.cpp264
5 files changed, 479 insertions, 12 deletions
diff --git a/qcwcn/wifi_hal/common.h b/qcwcn/wifi_hal/common.h
index 3ea962d..c7cfc94 100644
--- a/qcwcn/wifi_hal/common.h
+++ b/qcwcn/wifi_hal/common.h
@@ -94,6 +94,13 @@ typedef struct {
size_t flags_len;
} features_info;
+enum pkt_log_version {
+ PKT_LOG_V0 = 0, // UNSPECIFIED Target
+ PKT_LOG_V1 = 1, // ROME Base Target
+ PKT_LOG_V2 = 2, // HELIUM Base Target
+ PKT_LOG_V3 = 3, // LETHIUM Base target
+};
+
struct gscan_event_handlers_s;
struct rssi_monitor_event_handler_s;
struct cld80211_ctx;
@@ -154,6 +161,7 @@ typedef struct hal_info_s {
wifi_capa capa;
struct cld80211_ctx *cldctx;
bool apf_enabled;
+ pkt_log_version pkt_log_ver;
} hal_info;
wifi_error wifi_register_handler(wifi_handle handle, int cmd, nl_recvmsg_msg_cb_t func, void *arg);
diff --git a/qcwcn/wifi_hal/pkt_stats.h b/qcwcn/wifi_hal/pkt_stats.h
index d1cc71a..88a58c0 100644
--- a/qcwcn/wifi_hal/pkt_stats.h
+++ b/qcwcn/wifi_hal/pkt_stats.h
@@ -50,6 +50,9 @@
#define BW_OFFSET 8
#define INVALID_RSSI 255
+/* Based on pkt log V2, this type of event will triggered */
+#define PKTLOG_TYPE_PKT_SW_EVENT 10
+
#define PKT_INFO_FLG_TX_LOCAL_S 0x1
#define PKT_INFO_FLG_RX_HOST_RXD 0x2
#define PKT_INFO_FLG_TX_REMOTE_S 0x4
@@ -63,6 +66,30 @@
#define PKT_INFO_FLG_UNKNOWN_S 0x400
#define PKT_INFO_FLG_PKT_DUMP_V2 0x8000
+/* Depend on packet log version V2 this
+ * offset are define, for more info need to
+ * check from firmware side.
+ */
+#define TX_SUCCESS_TMS_OFFSET 56
+#define LINK_LAYER_TX_SQN_OFFSET 66
+#define RATE_CODE_OFFSET 68
+#define TX_STATUS_OFFSET 70
+#define TX_RSSI_OFFSET 71
+#define NO_RETRIES_OFFSET 75
+#define EXT_FLAGS_OFFSET 76
+#define BMAP_FAILED_OFFSET 84
+#define BMAP_ENQUEUED_OFFSET 92
+#define FRAME_CTRL_OFFSET 216
+#define QOS_CTRL_OFFSET 218
+
+/* MAX HT/VHT mcs index */
+#define MAX_VHT_MCS_IDX 10
+#define MAX_HT_MCS_IDX 8
+
+/* MAX CCK/OFDM rate index */
+#define MAX_CCK_MCS_IDX 4
+#define MAX_OFDM_MCS_IDX 8
+
/* MASK value of flags based on RX_STAT content.
* These are the events that carry Rx decriptor
*/
@@ -86,7 +113,8 @@ typedef struct {
typedef struct {
u16 flags;
u16 missed_cnt;
- u16 log_type;
+ u16 log_type : 8; //[7:0]
+ u16 mac_id : 8; //[15:8]
u16 size;
u32 timestamp;
u32 reserved;
@@ -323,6 +351,171 @@ typedef struct {
* if any event is missed.
*/
+/* PKT_LOG_V2 Base strcuture used to parse buffer */
+typedef struct {
+ u16 frm_ctrl;
+ u8 tx_ok;
+ u16 qos_ctrl;
+ u64 bmap_failed;
+ u64 bmap_enqueued;
+} __attribute__((packed)) node_pkt_stats;
+
+typedef u8 A_RATECODE;
+
+/* Rate Code as per PKT_LOG_V2 Version */
+typedef struct {
+ A_RATECODE rateCode;
+ u8 flags;
+} RATE_CODE;
+
+/* bandwidht type*/
+typedef enum {
+ BW_20MHZ,
+ BW_40MHZ,
+ BW_80MHZ,
+ BW_160MHZ,
+} bandwidth;
+
+/* Preamble type*/
+typedef enum {
+ WIFI_HW_RATECODE_PREAM_OFDM = 0,
+ WIFI_HW_RATECODE_PREAM_CCK = 1,
+ WIFI_HW_RATECODE_PREAM_HT = 2,
+ WIFI_HW_RATECODE_PREAM_VHT = 3,
+ WIFI_HW_RATECODE_PREAM_COUNT,
+} WIFI_HW_RATECODE_PREAM_TYPE;
+
+/**
+ * struct index_data_rate_type - non vht data rate type
+ * @rate_index: cck rate index
+ * @cck_rate: CCK supported rate table
+ */
+struct index_data_rate_cck_type {
+ uint8_t rate_index;
+ uint16_t cck_rate[2];
+};
+
+/**
+ * struct index_data_rate_type - non vht data rate type
+ * @rate_index: ofdm rate index
+ * @ofdm__rate: OFDM supported rate table
+ */
+struct index_data_rate_ofdm_type {
+ uint8_t rate_index;
+ uint16_t ofdm_rate[2];
+};
+
+/*Below CCK/OFDM table refer from firmware Arch */
+/* Rate Table Based on CCK */
+static struct index_data_rate_cck_type cck_mcs_nss1[] = {
+ /*RC LKbps SKbps */
+ {0x40, {11000, 11000} },
+ {0x41, {5500, 5500} },
+ {0x42, {2000, 2000} },
+ {0x43, {1000, 1000} }
+};
+
+/* Rate Table Based on OFDM */
+static struct index_data_rate_ofdm_type ofdm_mcs_nss1[] = {
+ /*RC LKbps SKbps */
+ {0x00, {48000, 48000} },
+ {0x01, {34000, 24000} },
+ {0x02, {12000, 12000} },
+ {0x03, {6000, 6000} },
+ {0x04, {54000, 54000} },
+ {0x05, {36000, 36000} },
+ {0x06, {18000, 18000} },
+ {0x07, {9000, 9000} }
+};
+
+/**
+ * struct index_data_rate_type - non vht data rate type
+ * @mcs_index: mcs rate index
+ * @ht20_rate: HT20 supported rate table
+ * @ht40_rate: HT40 supported rate table
+ */
+struct index_data_rate_type {
+ uint8_t mcs_index;
+ uint16_t ht20_rate[2];
+ uint16_t ht40_rate[2];
+};
+
+/**
+ * struct index_vht_data_rate_type - vht data rate type
+ * @mcs_index: mcs rate index
+ * @ht20_rate: VHT20 supported rate table
+ * @ht40_rate: VHT40 supported rate table
+ * @ht80_rate: VHT80 supported rate table
+ */
+struct index_vht_data_rate_type {
+ uint8_t mcs_index;
+ uint16_t ht20_rate[2];
+ uint16_t ht40_rate[2];
+ uint16_t ht80_rate[2];
+};
+
+/*Below HT/VHT table refer from Host Driver
+ * MCS Based rate table
+ * HT MCS parameters with Nss = 1
+ */
+static struct index_data_rate_type mcs_nss1[] = {
+ /* MCS L20 S20 L40 S40 */
+ {0, {65, 72}, {135, 150 } },
+ {1, {130, 144}, {270, 300 } },
+ {2, {195, 217}, {405, 450 } },
+ {3, {260, 289}, {540, 600 } },
+ {4, {390, 433}, {815, 900 } },
+ {5, {520, 578}, {1080, 1200} },
+ {6, {585, 650}, {1215, 1350} },
+ {7, {650, 722}, {1350, 1500} }
+};
+
+/* HT MCS parameters with Nss = 2 */
+static struct index_data_rate_type mcs_nss2[] = {
+ /* MCS L20 S20 L40 S40 */
+ {0, {130, 144}, {270, 300 } },
+ {1, {260, 289}, {540, 600 } },
+ {2, {390, 433}, {810, 900 } },
+ {3, {520, 578}, {1080, 1200} },
+ {4, {780, 867}, {1620, 1800} },
+ {5, {1040, 1156}, {2160, 2400} },
+ {6, {1170, 1300}, {2430, 2700} },
+ {7, {1300, 1440}, {2700, 3000} }
+};
+
+/* MCS Based VHT rate table
+ * MCS parameters with Nss = 1
+ */
+static struct index_vht_data_rate_type vht_mcs_nss1[] = {
+ /* MCS L20 S20 L40 S40 L80 S80 */
+ {0, {65, 72 }, {135, 150}, {293, 325} },
+ {1, {130, 144}, {270, 300}, {585, 650} },
+ {2, {195, 217}, {405, 450}, {878, 975} },
+ {3, {260, 289}, {540, 600}, {1170, 1300} },
+ {4, {390, 433}, {810, 900}, {1755, 1950} },
+ {5, {520, 578}, {1080, 1200}, {2340, 2600} },
+ {6, {585, 650}, {1215, 1350}, {2633, 2925} },
+ {7, {650, 722}, {1350, 1500}, {2925, 3250} },
+ {8, {780, 867}, {1620, 1800}, {3510, 3900} },
+ {9, {865, 960}, {1800, 2000}, {3900, 4333} }
+};
+
+/*MCS parameters with Nss = 2*/
+static struct index_vht_data_rate_type vht_mcs_nss2[] = {
+ /* MCS L20 S20 L40 S40 L80 S80 */
+ {0, {130, 144}, {270, 300}, { 585, 650} },
+ {1, {260, 289}, {540, 600}, {1170, 1300} },
+ {2, {390, 433}, {810, 900}, {1755, 1950} },
+ {3, {520, 578}, {1080, 1200}, {2340, 2600} },
+ {4, {780, 867}, {1620, 1800}, {3510, 3900} },
+ {5, {1040, 1156}, {2160, 2400}, {4680, 5200} },
+ {6, {1170, 1300}, {2430, 2700}, {5265, 5850} },
+ {7, {1300, 1444}, {2700, 3000}, {5850, 6500} },
+ {8, {1560, 1733}, {3240, 3600}, {7020, 7800} },
+ {9, {1730, 1920}, {3600, 4000}, {7800, 8667} }
+};
+/*********************************************************/
+
#define RING_BUF_ENTRY_SIZE 512
#define PKT_STATS_BUF_SIZE 128
struct pkt_stats_s {
diff --git a/qcwcn/wifi_hal/wifi_hal.cpp b/qcwcn/wifi_hal/wifi_hal.cpp
index 8e8367c..25ec6d7 100644
--- a/qcwcn/wifi_hal/wifi_hal.cpp
+++ b/qcwcn/wifi_hal/wifi_hal.cpp
@@ -65,6 +65,7 @@
#define WIFI_HAL_CMD_SOCK_PORT 644
#define WIFI_HAL_EVENT_SOCK_PORT 645
+#define MAX_HW_VER_LENGTH 100
/*
* Defines for wifi_wait_for_driver_ready()
* Specify durations between polls and max wait time
@@ -494,6 +495,8 @@ wifi_error wifi_initialize(wifi_handle *handle)
struct nl_cb *cb = NULL;
int status = 0;
int index;
+ char hw_ver_type[MAX_HW_VER_LENGTH];
+ char *hw_name = NULL;
ALOGI("Initializing wifi");
hal_info *info = (hal_info *)malloc(sizeof(hal_info));
@@ -670,6 +673,24 @@ wifi_error wifi_initialize(wifi_handle *handle)
if (ret != WIFI_SUCCESS)
ALOGE("Failed to get supported logger feature set: %d", ret);
+ ret = wifi_get_firmware_version(iface_handle, hw_ver_type,
+ MAX_HW_VER_LENGTH);
+ if (ret == WIFI_SUCCESS) {
+ hw_name = strstr(hw_ver_type, "HW:");
+ if (hw_name) {
+ hw_name += strlen("HW:");
+ if (strncmp(hw_name, "QCA6174", 7) == 0)
+ info->pkt_log_ver = PKT_LOG_V1;
+ else
+ info->pkt_log_ver = PKT_LOG_V2;
+ } else {
+ info->pkt_log_ver = PKT_LOG_V0;
+ }
+ ALOGV("%s: hardware version type %d", __func__, info->pkt_log_ver);
+ } else {
+ ALOGE("Failed to get supported logger feature set: %d", ret);
+ }
+
ret = get_firmware_bus_max_size_supported(iface_handle);
if (ret != WIFI_SUCCESS) {
ALOGE("Failed to get supported bus size, error : %d", ret);
diff --git a/qcwcn/wifi_hal/wifilogger.cpp b/qcwcn/wifi_hal/wifilogger.cpp
index 38aad86..7e8efe6 100644
--- a/qcwcn/wifi_hal/wifilogger.cpp
+++ b/qcwcn/wifi_hal/wifilogger.cpp
@@ -147,7 +147,8 @@ wifi_error wifi_start_logging(wifi_interface_handle iface,
if (ret != WIFI_SUCCESS)
ALOGE("%s: Error %d happened. ", __FUNCTION__, ret);
- ALOGV("%s: Logging Started for %s.", __FUNCTION__, buffer_name);
+ ALOGV("%s: Logging Started for %s. with verboselevel %d",
+ __FUNCTION__, buffer_name,verbose_level);
rb_start_logging(&info->rb_infos[ring_id], verbose_level,
flags, max_interval_sec, min_data_size);
cleanup:
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);