am 0db016e..c125981 from mirror-m-wireless-internal-release
c125981 Wi-Fi HAL: Remove sending registration msg to driver
063058f WiFi-HAL: Process log completion event
cd2e2fd WiFi-HAL: Clean up wake lock event processing
d3ebf0d Wifi-HAL: Enable connectivity events
d8ed4eb Wifi-HAL: Changes as per Logging Header changes
6988c4d Wi-Fi HAL: Add support to get tdls capabilities
0910ea7 Wi-Fi HAL: Fix a GScan get cached results bug
ae226e1 Wi-Fi HAL: Updating the wifi_hal function table
16b2e84 Enable rx payload and few other stats in packet stats
0b7d2d5 Wi-Fi HAL: Add version field to the packet log structure
diff --git a/qcwcn/wifi_hal/common.h b/qcwcn/wifi_hal/common.h
index 2f87fbe..9236975 100644
--- a/qcwcn/wifi_hal/common.h
+++ b/qcwcn/wifi_hal/common.h
@@ -43,8 +43,8 @@
#include "nl80211_copy.h"
#include <utils/Log.h>
-#include "wifi_logger.h"
#include "rb_wrapper.h"
+#include "pkt_stats.h"
#define SOCKET_BUFFER_SIZE (32768U)
#define RECV_BUF_SIZE (4096)
@@ -54,6 +54,7 @@
#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#define MAC_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x"
+#define BIT(x) (1 << (x))
typedef int16_t s16;
typedef int32_t s32;
@@ -114,6 +115,7 @@
void (*on_ring_buffer_data) (char *ring_name, char *buffer, int buffer_size,
wifi_ring_buffer_status *status);
void (*on_alert) (wifi_request_id id, char *buffer, int buffer_size, int err_code);
+ struct pkt_stats_s *pkt_stats;
} 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/gscan.cpp b/qcwcn/wifi_hal/gscan.cpp
index fdf1c85..436d74b 100644
--- a/qcwcn/wifi_hal/gscan.cpp
+++ b/qcwcn/wifi_hal/gscan.cpp
@@ -1652,8 +1652,8 @@
}
/* Read num of cached scan results in this data chunk. Note that
* this value doesn't represent the number of unique gscan scan Ids
- * since the first scan id in this new chunck could be similar to
- * the last scan id in the previous chunck.
+ * since the first scan id in this new chunk could be similar to
+ * the last scan id in the previous chunk.
*/
numResults = nla_get_u32(tbVendor[
QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]);
@@ -1912,7 +1912,7 @@
{
u32 j = 0;
struct nlattr *scanResultsInfo, *wifiScanResultsInfo;
- int rem = 0;
+ int rem = 0, remResults = 0;
u32 len = 0, numScanResults = 0;
u32 i = mGetCachedResultsRspParams->cachedResultsStartingIndex;
ALOGE("%s: starting counter: %d", __FUNCTION__, i);
@@ -2007,10 +2007,10 @@
for (wifiScanResultsInfo = (struct nlattr *) nla_data(tb2[
QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]),
- rem = nla_len(tb2[
+ remResults = nla_len(tb2[
QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]);
- nla_ok(wifiScanResultsInfo, rem);
- wifiScanResultsInfo = nla_next(wifiScanResultsInfo, &(rem)))
+ nla_ok(wifiScanResultsInfo, remResults);
+ wifiScanResultsInfo = nla_next(wifiScanResultsInfo, &(remResults)))
{
struct nlattr *tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1];
nla_parse(tb3, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX,
diff --git a/qcwcn/wifi_hal/pkt_stats.h b/qcwcn/wifi_hal/pkt_stats.h
new file mode 100644
index 0000000..a8bd10e
--- /dev/null
+++ b/qcwcn/wifi_hal/pkt_stats.h
@@ -0,0 +1,266 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PKT_STATS_H_
+#define _PKT_STATS_H_
+
+/* Types of packet log events.
+ * Tx stats will be sent from driver with the help of multiple events.
+ * Need to parse the events PKTLOG_TYPE_TX_CTRL and PKTLOG_TYPE_TX_STAT
+ * as of now for the required stats. Rest of the events can ignored.
+ */
+#define PKTLOG_TYPE_TX_CTRL 1
+#define PKTLOG_TYPE_TX_STAT 2
+#define PKTLOG_TYPE_TX_MSDU_ID 3
+#define PKTLOG_TYPE_TX_FRM_HDR 4
+/* Rx stats will be sent from driver with event ID- PKTLOG_TYPE_RX_STAT */
+#define PKTLOG_TYPE_RX_STAT 5
+#define PKTLOG_TYPE_RC_FIND 6
+#define PKTLOG_TYPE_RC_UPDATE 7
+#define PKTLOG_TYPE_TX_VIRT_ADDR 8
+#define PKTLOG_TYPE_MAX 9
+
+/* Format of the packet stats event*/
+typedef struct {
+ u16 flags;
+ u16 missed_cnt;
+ u16 log_type;
+ u16 size;
+ u32 timestamp;
+} __attribute__((packed)) wh_pktlog_hdr_t;
+
+/*Rx stats specific structures. */
+
+struct rx_mpdu_start {
+ u32 reserved1 : 13; //[12:0]
+ u32 encrypted : 1; //[13]
+ u32 retry : 1; //[14]
+ u32 reserved2 : 1; //[15]
+ u32 seq_num : 12; //[27:16]
+ u32 reserved3 : 4; //[31:28]
+ u32 reserved4;
+ u32 reserved5 : 28; //[27:0]
+ u32 tid : 4; //[31:28]
+} __attribute__((packed));
+
+/*Indicates the decap-format of the packet*/
+enum {
+ RAW=0, // RAW: No decapsulation
+ NATIVEWIFI,
+ ETHERNET2, // (DIX)
+ ETHERNET // (SNAP/LLC)
+};
+
+struct rx_msdu_start {
+ u32 reserved1[2];
+ u32 reserved2 : 8; //[7:0]
+ u32 decap_format : 2; //[9:8]
+ u32 reserved3 : 22; //[31:10]
+} __attribute__((packed));
+
+struct rx_mpdu_end {
+ u32 reserved1 : 29; //[28:0]
+ u32 tkip_mic_err : 1; //[29]
+ u32 reserved2 : 2; //[31:30]
+} __attribute__((packed));
+
+#define PREAMBLE_L_SIG_RATE 0x04
+#define PREAMBLE_VHT_SIG_A_1 0x08
+#define PREAMBLE_VHT_SIG_A_2 0x0c
+
+#define BITMASK(x) ((1<<(x)) - 1 )
+/* Contains MCS related stats */
+struct rx_ppdu_start {
+ u32 reserved1[4];
+ u32 rssi_comb : 8; //[7:0]
+ u32 reserved2 : 24; //[31:8]
+ u32 l_sig_rate : 4; //[3:0]
+ u32 l_sig_rate_select : 1; //[4]
+ u32 reserved3 : 19; //[23:5]
+ u32 preamble_type : 8; //[31:24]
+ u32 ht_sig_vht_sig_a_1 : 24; //[23:0]
+ u32 reserved4 : 8; //[31:24]
+ u32 ht_sig_vht_sig_a_2 : 24; //[23:0]
+ u32 reserved5 : 8; //[31:25]
+ u32 reserved6[2];
+} __attribute__((packed));
+
+struct rx_ppdu_end {
+ u32 reserved1[17];
+ u32 wb_timestamp;
+ u32 reserved2[4];
+} __attribute__((packed));
+
+#define RX_HTT_HDR_STATUS_LEN 64
+typedef struct {
+ u32 reserved1[2];
+ struct rx_mpdu_start mpdu_start;
+ struct rx_msdu_start msdu_start;
+ u32 reserved2[5];
+ struct rx_mpdu_end mpdu_end;
+ struct rx_ppdu_start ppdu_start;
+ struct rx_ppdu_end ppdu_end;
+ char rx_hdr_status[RX_HTT_HDR_STATUS_LEN];
+}__attribute__((packed)) rb_pkt_stats_t;
+
+/*Tx stats specific structures. */
+struct ppdu_status {
+ u32 reserved1 : 31; //[30:0]
+ u32 tx_ok : 1; //[31]
+ u32 reserved2[10];
+ u32 ack_rssi_ave : 8; //[7:0]
+ u32 reserved3 : 16; //[23:8]
+ u32 total_tries : 5; //[28:24]
+ u32 reserved4 : 3; //[31:29]
+ u32 reserved5[4];
+} __attribute__((packed));
+
+/*Contains tx timestamp*/
+struct try_status {
+ u32 timestamp : 23; //[22:0]
+ u32 reserved : 9; //[23]
+} __attribute__((packed));
+
+struct try_list {
+ struct try_status try_00;
+ u32 reserved[15];
+} __attribute__((packed));
+
+
+struct tx_ppdu_end {
+ struct try_list try_list;
+ struct ppdu_status stat;
+} __attribute__((packed));
+
+/*Tx MCS and data rate ralated stats */
+struct series_bw {
+ u32 reserved1 : 28; //[27:0]
+ u32 short_gi : 1; //[28]
+ u32 reserved2 : 3; //[31:29]
+ u32 reserved3 : 24; //[23:21]
+ u32 rate : 4; //[27:24]
+ u32 nss : 2; //[29:28]
+ u32 preamble_type : 2; //[31:30]
+ u32 reserved4[2];
+} __attribute__((packed));
+
+enum tx_bw {
+ BW_20_MHZ,
+ BW_40_MHZ,
+ BW_80_MHZ,
+ BW_160_MHZ
+};
+
+#define DATA_PROTECTED 14
+struct tx_ppdu_start {
+ u32 reserved1[2];
+ u32 start_seq_num : 12; //[11:0]
+ u32 reserved2 : 20; //[31:12]
+ u32 reserved3[11];
+ u32 reserved4 : 16; //[15:0]
+ u32 frame_control : 16; //[31:16]
+ u32 reserved5 : 16; //[23:21]
+ u32 qos_ctl : 16; //[31:16]
+ u32 reserved6[4];
+ u32 reserved7 : 24; //[23:21]
+ u32 valid_s0_bw20 : 1; //[24]
+ u32 valid_s0_bw40 : 1; //[25]
+ u32 valid_s0_bw80 : 1; //[26]
+ u32 valid_s0_bw160 : 1; //[27]
+ u32 valid_s1_bw20 : 1; //[28]
+ u32 valid_s1_bw40 : 1; //[29]
+ u32 valid_s1_bw80 : 1; //[30]
+ u32 valid_s1_bw160 : 1; //[31]
+ struct series_bw s0_bw20;
+ struct series_bw s0_bw40;
+ struct series_bw s0_bw80;
+ struct series_bw s0_bw160;
+ struct series_bw s1_bw20;
+ struct series_bw s1_bw40;
+ struct series_bw s1_bw80;
+ struct series_bw s1_bw160;
+ u32 reserved8[3];
+} __attribute__((packed));
+
+#define PKTLOG_MAX_TXCTL_WORDS 57 /* +2 words for bitmap */
+typedef struct {
+ u32 reserved1[3];
+ union {
+ u32 txdesc_ctl[PKTLOG_MAX_TXCTL_WORDS];
+ struct tx_ppdu_start ppdu_start;
+ }u;
+} __attribute__((packed)) wh_pktlog_txctl;
+
+/* Required stats are spread across multiple
+ * events(PKTLOG_TYPE_TX_CTRL and PKTLOG_TYPE_TX_STAT here).
+ * Need to aggregate the stats collected in each event and write to the
+ * ring buffer only after receiving all the expected stats.
+ * Need to preserve the stats in hal_info till then and use tx_stats_events
+ * flag to track the events.
+ * prev_seq_no: Can used to track the events that come from driver and identify
+ * if any event is missed.
+ */
+
+#define RING_BUF_ENTRY_SIZE 512
+struct pkt_stats_s {
+ u8 tx_stats_events;
+ u32 prev_seq_no;
+ /* TODO: Need to handle the case if size of the stats are more
+ * than 512 bytes. Currently, the tx size is 34 bytes and ring buffer entry
+ * size is 12 bytes.
+ */
+ u8 tx_stats[RING_BUF_ENTRY_SIZE];
+};
+
+typedef union {
+ struct {
+ u16 rate : 4;
+ u16 nss : 2;
+ u16 preamble : 2;
+ u16 bw : 8;
+ } mcs_s;
+ u16 mcs;
+} MCS;
+
+typedef struct drv_msg_s
+{
+ u16 length;
+ u16 event_type;
+ u32 timestamp_low;
+ u32 timestamp_high;
+ union {
+ struct {
+ u32 version;
+ u32 msg_seq_no;
+ u32 payload_len;
+ u8 payload[0];
+ } __attribute__((packed)) pkt_stats_event;
+ } u;
+} __attribute__((packed)) drv_msg_t;
+
+#endif
diff --git a/qcwcn/wifi_hal/rb_wrapper.h b/qcwcn/wifi_hal/rb_wrapper.h
index 6b78ec9..a0b6b1b 100644
--- a/qcwcn/wifi_hal/rb_wrapper.h
+++ b/qcwcn/wifi_hal/rb_wrapper.h
@@ -53,4 +53,5 @@
int is_rb_name_match(struct rb_info *rb_info, char *name);
wifi_error ring_buffer_write(struct rb_info *rb_info, u8 *buf, size_t length,
int no_of_records);
+void push_out_rb_data(void *cb_ctx);
#endif /* __RB_WRAPPER_H */
diff --git a/qcwcn/wifi_hal/tdls.cpp b/qcwcn/wifi_hal/tdls.cpp
index dcd1e16..a01ea42 100755
--- a/qcwcn/wifi_hal/tdls.cpp
+++ b/qcwcn/wifi_hal/tdls.cpp
@@ -252,6 +252,38 @@
mTDLSgetStatusRspParams.global_operating_class);
}
break;
+ case QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_CAPABILITIES:
+ {
+ struct nlattr *tb_vendor[
+ QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_MAX + 1];
+ nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_MAX,
+ (struct nlattr *)mVendorData,
+ mDataLen, NULL);
+
+ memset(&mTDLSgetCaps, 0, sizeof(wifiTdlsCapabilities));
+
+ if (!tb_vendor[
+ QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_MAX_CONC_SESSIONS]
+ )
+ {
+ ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_"
+ "MAX_CONC_SESSIONS not found", __FUNCTION__);
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+ mTDLSgetCaps.maxConcurrentTdlsSessionNum = get_u32(tb_vendor[
+ QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_MAX_CONC_SESSIONS]);
+
+ if (!tb_vendor[
+ QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_FEATURES_SUPPORTED])
+ {
+ ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_"
+ "FEATURES_SUPPORTED not found", __FUNCTION__);
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+ mTDLSgetCaps.tdlsSupportedFeatures = get_u32(tb_vendor[
+ QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_FEATURES_SUPPORTED]);
+ }
+ break;
default :
ALOGE("%s: Wrong TDLS subcmd response received %d",
__FUNCTION__, mSubcmd);
@@ -292,6 +324,27 @@
return WifiCommand::requestResponse(mMsg);
}
+void TdlsCommand::getCapsRspParams(wifi_tdls_capabilities *caps)
+{
+ caps->max_concurrent_tdls_session_num =
+ mTDLSgetCaps.maxConcurrentTdlsSessionNum;
+ caps->is_global_tdls_supported =
+ !!(mTDLSgetCaps.tdlsSupportedFeatures & IS_GLOBAL_TDLS_SUPPORTED);
+ caps->is_per_mac_tdls_supported =
+ !!(mTDLSgetCaps.tdlsSupportedFeatures & IS_PER_MAC_TDLS_SUPPORTED);
+ caps->is_off_channel_tdls_supported =
+ !!(mTDLSgetCaps.tdlsSupportedFeatures & IS_OFF_CHANNEL_TDLS_SUPPORTED);
+ ALOGI("TDLS capabilities:");
+ ALOGI("max_concurrent_tdls_session_numChannel : %d\n",
+ caps->max_concurrent_tdls_session_num);
+ ALOGI("is_global_tdls_supported : %d\n",
+ caps->is_global_tdls_supported);
+ ALOGI("is_per_mac_tdls_supported : %d\n",
+ caps->is_per_mac_tdls_supported);
+ ALOGI("is_off_channel_tdls_supported : %d \n",
+ caps->is_off_channel_tdls_supported);
+}
+
/* wifi_enable_tdls - enables TDLS-auto mode for a specific route
*
* params specifies hints, which provide more information about
@@ -429,6 +482,7 @@
cleanup:
ALOGI("%s: Exit", __FUNCTION__);
+ delete pTdlsCommand;
return (wifi_error)ret;
}
@@ -482,3 +536,50 @@
ALOGI("%s: Exit", __FUNCTION__);
return (wifi_error)ret;
}
+
+/* return the current HW + Firmware combination's TDLS capabilities */
+wifi_error wifi_get_tdls_capabilities(wifi_interface_handle iface,
+ wifi_tdls_capabilities *capabilities)
+{
+ int ret = 0;
+ TdlsCommand *pTdlsCommand;
+ ALOGI("%s: Enter", __FUNCTION__);
+
+ if (capabilities == NULL) {
+ ALOGE("%s: capabilities is NULL", __FUNCTION__);
+ return WIFI_ERROR_INVALID_ARGS;
+ }
+
+ interface_info *iinfo = getIfaceInfo(iface);
+ wifi_handle handle = getWifiHandle(iface);
+ pTdlsCommand = TdlsCommand::instance(handle);
+
+ if (pTdlsCommand == NULL) {
+ ALOGE("%s: Error TdlsCommand NULL", __FUNCTION__);
+ return WIFI_ERROR_UNKNOWN;
+ }
+ pTdlsCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_CAPABILITIES);
+
+ /* Create the message */
+ ret = pTdlsCommand->create();
+ if (ret < 0)
+ goto cleanup;
+
+ ret = pTdlsCommand->set_iface_id(iinfo->name);
+ if (ret < 0)
+ goto cleanup;
+
+ ret = pTdlsCommand->requestResponse();
+ if (ret != 0) {
+ ALOGE("%s: requestResponse Error:%d", __FUNCTION__, ret);
+ goto cleanup;
+ }
+ pTdlsCommand->getCapsRspParams(capabilities);
+
+cleanup:
+ ALOGI("%s: Exit", __FUNCTION__);
+ if (ret < 0)
+ memset(capabilities, 0, sizeof(wifi_tdls_capabilities));
+ delete pTdlsCommand;
+ return (wifi_error)ret;
+}
diff --git a/qcwcn/wifi_hal/tdlsCommand.h b/qcwcn/wifi_hal/tdlsCommand.h
index 48524bd..1ee9e32 100755
--- a/qcwcn/wifi_hal/tdlsCommand.h
+++ b/qcwcn/wifi_hal/tdlsCommand.h
@@ -66,6 +66,15 @@
{
#endif /* __cplusplus */
+#define IS_GLOBAL_TDLS_SUPPORTED BIT(0)
+#define IS_PER_MAC_TDLS_SUPPORTED BIT(1)
+#define IS_OFF_CHANNEL_TDLS_SUPPORTED BIT(2)
+
+typedef struct {
+ int maxConcurrentTdlsSessionNum;
+ u32 tdlsSupportedFeatures;
+} wifiTdlsCapabilities;
+
class TdlsCommand: public WifiVendorCommand
{
private:
@@ -73,6 +82,7 @@
wifi_tdls_status mTDLSgetStatusRspParams;
wifi_request_id mRequestId;
wifi_tdls_handler mHandler;
+ wifiTdlsCapabilities mTDLSgetCaps;
TdlsCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd);
@@ -93,6 +103,8 @@
virtual void unregisterHandler(u32 subCmd);
virtual void getStatusRspParams(wifi_tdls_status *status);
+
+ virtual void getCapsRspParams(wifi_tdls_capabilities *caps);
};
#ifdef __cplusplus
diff --git a/qcwcn/wifi_hal/vendor_definitions.h b/qcwcn/wifi_hal/vendor_definitions.h
index 6ac7283..8fc3470 100644
--- a/qcwcn/wifi_hal/vendor_definitions.h
+++ b/qcwcn/wifi_hal/vendor_definitions.h
@@ -87,6 +87,8 @@
#define QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET 76
/* WiFiLogger Get Ring Data */
#define QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA 77
+/* Get tdls capabilities */
+#define QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_CAPABILITIES 78
#endif
@@ -843,6 +845,19 @@
QCA_WLAN_VENDOR_ATTR_TDLS_STATE_AFTER_LAST - 1,
};
+enum qca_wlan_vendor_attr_tdls_get_capabilities
+{
+ QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_INVALID = 0,
+
+ QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_MAX_CONC_SESSIONS,
+ QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_FEATURES_SUPPORTED,
+
+ /* keep last */
+ QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_AFTER_LAST,
+ QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_MAX =
+ QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_AFTER_LAST - 1,
+};
+
enum qca_wlan_vendor_attr_get_supported_features
{
QCA_WLAN_VENDOR_ATTR_FEATURE_SET_INVALID = 0,
diff --git a/qcwcn/wifi_hal/wifi_hal.cpp b/qcwcn/wifi_hal/wifi_hal.cpp
index 6f7254d..a6fd004 100644
--- a/qcwcn/wifi_hal/wifi_hal.cpp
+++ b/qcwcn/wifi_hal/wifi_hal.cpp
@@ -134,7 +134,6 @@
{
int *err = (int *)arg;
*err = 0;
- ALOGD("%s invoked",__func__);
return NL_STOP;
}
@@ -142,7 +141,6 @@
{
int *ret = (int *)arg;
*ret = 0;
- ALOGD("%s called",__func__);
return NL_SKIP;
}
@@ -157,7 +155,6 @@
}
static int no_seq_check(struct nl_msg *msg, void *arg)
{
- ALOGD("no_seq_check received");
return NL_OK;
}
@@ -203,6 +200,16 @@
return WIFI_ERROR_UNKNOWN;
}
+ /* Set the socket buffer size */
+ if (nl_socket_set_buffer_size(user_sock, (256*1024), 0) < 0) {
+ ALOGE("Could not set size for user_sock: %s",
+ strerror(errno));
+ /* continue anyway with the default (smaller) buffer */
+ }
+ else {
+ ALOGI("nl_socket_set_buffer_size successful for user_sock");
+ }
+
struct nl_cb *cb = nl_socket_get_cb(user_sock);
if (cb == NULL) {
ALOGE("Could not get cb");
@@ -229,36 +236,6 @@
return WIFI_SUCCESS;
}
-static wifi_error wifi_register_for_debug_events(hal_info *info)
-{
- u8 buf[sizeof(tAniNlHdr) + sizeof(tAniNlAppRegReq)];
- int sock_fd = info->user_sock->s_fd;
- tAniNlHdr *wnl;
- tAniNlAppRegReq *regReq;
- struct nlmsghdr *nlh;
-
- memset(buf, 0, sizeof(buf));
-
- nlh = (struct nlmsghdr *)buf;
-
- nlh->nlmsg_len = sizeof(tAniNlHdr) + sizeof(tAniNlAppRegReq);
- nlh->nlmsg_pid = getpid();
- nlh->nlmsg_type = ANI_NL_MSG_PUMAC;
- nlh->nlmsg_flags = NLM_F_REQUEST;
- nlh->nlmsg_seq++;
- wnl = (tAniNlHdr *)nlh;
- wnl->radio = 0;
- wnl->wmsg.length = sizeof(tAniNlAppRegReq);
- wnl->wmsg.type = htons(ANI_NL_MSG_LOG_REG_TYPE);
- regReq = (tAniNlAppRegReq *)(wnl + 1);
- regReq->pid = getpid();
- if (sendto(sock_fd, (char*)wnl, nlh->nlmsg_len,0,NULL, 0) < 0) {
- ALOGI("Failed to send registration msg");
- return WIFI_ERROR_UNKNOWN;
- }
- return WIFI_SUCCESS;
-}
-
/*initialize function pointer table with Qualcomm HAL API*/
wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn) {
if (fn == NULL) {
@@ -281,14 +258,36 @@
fn->wifi_set_significant_change_handler = wifi_set_significant_change_handler;
fn->wifi_reset_significant_change_handler = wifi_reset_significant_change_handler;
fn->wifi_get_gscan_capabilities = wifi_get_gscan_capabilities;
+ fn->wifi_set_link_stats = wifi_set_link_stats;
fn->wifi_get_link_stats = wifi_get_link_stats;
+ fn->wifi_clear_link_stats = wifi_clear_link_stats;
fn->wifi_get_valid_channels = wifi_get_valid_channels;
fn->wifi_rtt_range_request = wifi_rtt_range_request;
fn->wifi_rtt_range_cancel = wifi_rtt_range_cancel;
fn->wifi_get_rtt_capabilities = wifi_get_rtt_capabilities;
fn->wifi_set_nodfs_flag = wifi_set_nodfs_flag;
+ fn->wifi_start_logging = wifi_start_logging;
fn->wifi_set_epno_list = wifi_set_epno_list;
fn->wifi_set_country_code = wifi_set_country_code;
+ fn->wifi_enable_tdls = wifi_enable_tdls;
+ fn->wifi_disable_tdls = wifi_disable_tdls;
+ fn->wifi_get_tdls_status = wifi_get_tdls_status;
+ fn->wifi_get_tdls_capabilities = wifi_get_tdls_capabilities;
+ fn->wifi_get_firmware_memory_dump = wifi_get_firmware_memory_dump;
+ fn->wifi_set_log_handler = wifi_set_log_handler;
+ fn->wifi_set_alert_handler = wifi_set_alert_handler;
+ fn->wifi_get_firmware_version = wifi_get_firmware_version;
+ fn->wifi_get_ring_buffers_status = wifi_get_ring_buffers_status;
+ fn->wifi_get_logger_supported_feature_set = wifi_get_logger_supported_feature_set;
+ fn->wifi_get_ring_data = wifi_get_ring_data;
+ fn->wifi_get_driver_version = wifi_get_driver_version;
+ fn->wifi_set_passpoint_list = wifi_set_passpoint_list;
+ fn->wifi_reset_passpoint_list = wifi_reset_passpoint_list;
+ fn->wifi_set_bssid_blacklist = wifi_set_bssid_blacklist;
+ fn->wifi_enable_lazy_roam = wifi_enable_lazy_roam;
+ fn->wifi_set_bssid_preference = wifi_set_bssid_preference;
+ fn->wifi_set_gscan_roam_params = wifi_set_gscan_roam_params;
+ fn->wifi_set_ssid_white_list = wifi_set_ssid_white_list;
return WIFI_SUCCESS;
}
@@ -400,7 +399,7 @@
ret = wifi_init_user_sock(info);
if (ret != WIFI_SUCCESS) {
ALOGE("Failed to alloc user socket");
- return ret;
+ goto unload;
}
if (!is_wifi_driver_loaded()) {
@@ -453,6 +452,15 @@
goto unload;
}
+ info->pkt_stats = (struct pkt_stats_s *)malloc(sizeof(struct pkt_stats_s));
+ if (!info->pkt_stats) {
+ ALOGE("%s: malloc Failed for size: %d",
+ __FUNCTION__, sizeof(struct pkt_stats_s));
+ ret = WIFI_ERROR_OUT_OF_MEMORY;
+ goto unload;
+ }
+
+
ALOGI("Initialized Wifi HAL Successfully; vendor cmd = %d Supported"
" features : %x", NL80211_CMD_VENDOR, info->supported_feature_set);
@@ -465,6 +473,7 @@
if (info) {
if (info->cmd) free(info->cmd);
if (info->event_cb) free(info->event_cb);
+ if (info->user_sock) nl_socket_free(info->user_sock);
free(info);
}
}
@@ -509,6 +518,7 @@
info->user_sock = NULL;
}
+ free(info->pkt_stats);
wifi_logger_ring_buffers_deinit(info);
(*cleaned_up_handler)(handle);
@@ -564,10 +574,6 @@
info->in_event_loop = true;
}
- if (wifi_register_for_debug_events(info)) {
- ALOGE("Failed to register for diag events");
- }
-
pollfd pfd[2];
memset(&pfd, 0, 2*sizeof(pfd[0]));
@@ -608,7 +614,6 @@
wifi_handle handle = (wifi_handle)arg;
hal_info *info = getHalInfo(handle);
- //ALOGI("Event triggered");
diag_message_handler(info, msg);
return NL_OK;
diff --git a/qcwcn/wifi_hal/wifilogger.cpp b/qcwcn/wifi_hal/wifilogger.cpp
index cffc1b4..2f9994b 100644
--- a/qcwcn/wifi_hal/wifilogger.cpp
+++ b/qcwcn/wifi_hal/wifilogger.cpp
@@ -158,7 +158,7 @@
/* Function to get each ring related info */
wifi_error wifi_get_ring_buffers_status(wifi_interface_handle iface,
u32 *num_buffers,
- wifi_ring_buffer_status **status)
+ wifi_ring_buffer_status *status)
{
int ret = 0;
interface_info *ifaceInfo = getIfaceInfo(iface);
@@ -168,16 +168,16 @@
struct rb_info *rb_info;
int rb_id;
- *status = (wifi_ring_buffer_status *)malloc(
- NUM_RING_BUFS * sizeof(
- wifi_ring_buffer_status));
- if (*status == NULL) {
+ if ((*num_buffers) < NUM_RING_BUFS) {
+ ALOGE("%s: Input num_buffers:%d cannot be accommodated, "
+ "Total ring buffer num:%d", __FUNCTION__, num_buffers,
+ NUM_RING_BUFS);
*num_buffers = 0;
return WIFI_ERROR_OUT_OF_MEMORY;
}
for (rb_id = 0; rb_id < NUM_RING_BUFS; rb_id++) {
rb_info = &info->rb_infos[rb_id];
- rbs = *status + rb_id;
+ rbs = status + rb_id;
get_rb_status(rb_info, rbs);
}
@@ -185,6 +185,23 @@
return (wifi_error)ret;
}
+void push_out_all_ring_buffers(hal_info *info)
+{
+ int rb_id;
+
+ for (rb_id = 0; rb_id < NUM_RING_BUFS; rb_id++) {
+ push_out_rb_data(&info->rb_infos[rb_id]);
+ }
+}
+
+void send_alert(hal_info *info, int reason_code)
+{
+ //TODO check locking
+ if (info->on_alert) {
+ info->on_alert(0, NULL, 0, reason_code);
+ }
+}
+
void WifiLoggerCommand::setFeatureSet(u32 *support) {
mSupportedSet = support;
}
@@ -321,14 +338,14 @@
return (wifi_error)ret;
}
-void WifiLoggerCommand::setVersionInfo(char **buffer, int *buffer_size) {
+void WifiLoggerCommand::setVersionInfo(char *buffer, int buffer_size) {
mVersion = buffer;
mVersionLen = buffer_size;
}
/* Function to send enable request to the wifi driver.*/
wifi_error wifi_get_firmware_version(wifi_interface_handle iface,
- char **buffer, int *buffer_size)
+ char *buffer, int buffer_size)
{
int requestId, ret = 0;
WifiLoggerCommand *wifiLoggerCommand;
@@ -391,7 +408,7 @@
/* Function to get wlan driver version.*/
wifi_error wifi_get_driver_version(wifi_interface_handle iface,
- char **buffer, int *buffer_size)
+ char *buffer, int buffer_size)
{
int requestId, ret = 0;
@@ -578,7 +595,7 @@
{
ALOGV("WifiLoggerCommand %p constructed", this);
mVersion = NULL;
- mVersionLen = NULL;
+ mVersionLen = 0;
mRequestId = id;
memset(&mHandler, 0,sizeof(mHandler));
mWaitforRsp = false;
@@ -766,7 +783,7 @@
u32 status;
int ret = WIFI_SUCCESS;
int i = 0;
- u32 len = 0, version;
+ int len = 0, version;
char version_type[20];
WifiVendorCommand::handleResponse(reply);
@@ -792,19 +809,16 @@
memcpy(version_type, "Firmware", strlen("Firmware"));
version = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
}
- if (len) {
- *mVersion = (char *)malloc(len*(sizeof(char)) + 1);
- if (!(*mVersion)) {
- ALOGE("%s: Failed to allocate memory for Version.",
- __FUNCTION__);
- return WIFI_ERROR_OUT_OF_MEMORY;
- }
- memset(*mVersion, 0, (len*(sizeof(char))) + 1);
- *mVersionLen = len;
- memcpy(*mVersion, nla_data(tb_vendor[version]), len);
+ if (len && mVersion && mVersionLen) {
+ memset(mVersion, 0, mVersionLen);
+ /* if len is greater than the incoming length then
+ accommodate 1 lesser than mVersionLen to have the
+ string terminated with '\0' */
+ len = (len > mVersionLen)? (mVersionLen - 1) : len;
+ memcpy(mVersion, nla_data(tb_vendor[version]), len);
ALOGD("%s: WLAN version len : %d", __FUNCTION__, len);
ALOGD("%s: WLAN %s version : %s ", __FUNCTION__,
- version_type, *mVersion);
+ version_type, mVersion);
}
}
break;
diff --git a/qcwcn/wifi_hal/wifilogger_diag.cpp b/qcwcn/wifi_hal/wifilogger_diag.cpp
index 1a1520c..7aff7c4 100644
--- a/qcwcn/wifi_hal/wifilogger_diag.cpp
+++ b/qcwcn/wifi_hal/wifilogger_diag.cpp
@@ -32,8 +32,32 @@
#include <netlink/genl/family.h>
#include <netlink/genl/ctrl.h>
#include <linux/rtnetlink.h>
+#include <netinet/in.h>
#include "wifiloggercmd.h"
+#include "wifilogger_event_defs.h"
#include "wifilogger_diag.h"
+#include "wifilogger_vendor_tag_defs.h"
+#include "pkt_stats.h"
+
+#define RING_BUF_ENTRY_SIZE 512
+#define MAX_CONNECTIVITY_EVENTS 15 // should match the value in wifi_logger.h
+static event_remap_t events[MAX_CONNECTIVITY_EVENTS] = {
+ {WLAN_PE_DIAG_ASSOC_REQ_EVENT, WIFI_EVENT_ASSOCIATION_REQUESTED},
+ {WLAN_PE_DIAG_AUTH_COMP_EVENT, WIFI_EVENT_AUTH_COMPLETE},
+ {WLAN_PE_DIAG_ASSOC_COMP_EVENT, WIFI_EVENT_ASSOC_COMPLETE},
+ {WLAN_PE_DIAG_AUTH_START_EVENT, WIFI_EVENT_FW_AUTH_STARTED},
+ {WLAN_PE_DIAG_ASSOC_START_EVENT, WIFI_EVENT_FW_ASSOC_STARTED},
+ {WLAN_PE_DIAG_REASSOC_START_EVENT, WIFI_EVENT_FW_RE_ASSOC_STARTED},
+ {WLAN_PE_DIAG_SCAN_REQ_EVENT, WIFI_EVENT_DRIVER_SCAN_REQUESTED},
+ {WLAN_PE_DIAG_SCAN_RES_FOUND_EVENT, WIFI_EVENT_DRIVER_SCAN_RESULT_FOUND},
+ {WLAN_PE_DIAG_SCAN_COMP_EVENT, WIFI_EVENT_DRIVER_SCAN_COMPLETE},
+ {WLAN_PE_DIAG_DISASSOC_REQ_EVENT, WIFI_EVENT_DISASSOCIATION_REQUESTED},
+ {WLAN_PE_DIAG_ASSOC_REQ_EVENT, WIFI_EVENT_RE_ASSOCIATION_REQUESTED},
+ {WLAN_PE_DIAG_ROAM_AUTH_START_EVENT, WIFI_EVENT_ROAM_AUTH_STARTED},
+ {WLAN_PE_DIAG_ROAM_AUTH_COMP_EVENT, WIFI_EVENT_ROAM_AUTH_COMPLETE},
+ {WLAN_PE_DIAG_ROAM_ASSOC_START_EVENT, WIFI_EVENT_ROAM_ASSOC_STARTED},
+ {WLAN_PE_DIAG_ROAM_ASSOC_COMP_EVENT, WIFI_EVENT_ROAM_ASSOC_COMPLETE},
+};
tlv_log* addLoggerTlv(u16 type, u16 length, u8* value, tlv_log *pOutTlv)
{
@@ -45,121 +69,1378 @@
return((tlv_log *)((u8 *)pOutTlv + sizeof(tlv_log) + length));
}
-static int process_wakelock_event(hal_info *info, u8* buf, int length)
+int add_reason_code_tag(tlv_log **tlvs, u16 reason_code)
{
- wlan_wake_lock_event_t *pWlanWakeLockEvent;
- wake_lock_event *pWakeLockEvent = NULL;
- wifi_power_event *pPowerEvent = NULL;
- wifi_ring_buffer_entry *pRingBufferEntry = NULL;
- int len_wakelock_event = 0, len_power_event = 0, ret = 0;
- int len_ring_buffer_entry = 0, num_records = 0;
+ *tlvs = addLoggerTlv(WIFI_TAG_REASON_CODE, sizeof(u16),
+ (u8 *)&reason_code, *tlvs);
+ return (sizeof(tlv_log) + sizeof(u16));
+}
+
+int add_status_tag(tlv_log **tlvs, int status)
+{
+ *tlvs = addLoggerTlv(WIFI_TAG_STATUS, sizeof(int),
+ (u8 *)&status, *tlvs);
+ return (sizeof(tlv_log) + sizeof(int));
+}
+
+static wifi_error update_connectivity_ring_buf(hal_info *info,
+ wifi_ring_buffer_entry *rbe,
+ u32 size)
+{
+ struct timeval time;
+ u32 total_length = size + sizeof(wifi_ring_buffer_entry);
+
+ rbe->entry_size = size;
+ rbe->flags = RING_BUFFER_ENTRY_FLAGS_HAS_BINARY |
+ RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP;
+ rbe->type = ENTRY_TYPE_CONNECT_EVENT;
+ gettimeofday(&time,NULL);
+ rbe->timestamp = time.tv_usec + time.tv_sec * 1000 * 1000;
+
+ /* Write if verbose level and handler are set */
+ if (info->rb_infos[CONNECTIVITY_EVENTS_RB_ID].verbose_level >= 1 &&
+ info->on_ring_buffer_data)
+ return ring_buffer_write(&info->rb_infos[CONNECTIVITY_EVENTS_RB_ID],
+ (u8*)rbe, total_length, 1);
+
+ return WIFI_SUCCESS;
+}
+
+static wifi_error process_bt_coex_scan_event(hal_info *info,
+ u32 id, u8* buf, int length)
+{
+ wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
+ wifi_ring_buffer_entry *pRingBufferEntry;
tlv_log *pTlv;
+ int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
+ u8 out_buf[RING_BUF_ENTRY_SIZE];
+ wifi_error status;
- ALOGD("Received a wake lock event");
+ pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
+ memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE);
+ pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
+ (pRingBufferEntry + 1);
+ pTlv = &pConnectEvent->tlvs[0];
- pWlanWakeLockEvent = (wlan_wake_lock_event_t *)(buf);
- ALOGD("wle status = %d reason %d timeout %d name_len %d name %s \n",
- pWlanWakeLockEvent->status, pWlanWakeLockEvent->reason,
- pWlanWakeLockEvent->timeout, pWlanWakeLockEvent->name_len,
- pWlanWakeLockEvent->name);
+ if (id == EVENT_WLAN_BT_COEX_BT_SCAN_START) {
+ wlan_bt_coex_bt_scan_start_payload_type *pBtScanStart;
+ bt_coex_bt_scan_start_vendor_data_t btScanStartVenData;
- len_wakelock_event = sizeof(wake_lock_event) +
- pWlanWakeLockEvent->name_len + 1;
+ pConnectEvent->event = WIFI_EVENT_BT_COEX_BT_SCAN_START;
- pWakeLockEvent = (wake_lock_event *)malloc(len_wakelock_event);
- if (pWakeLockEvent == NULL) {
- ALOGE("%s: Failed to allocate memory", __func__);
- goto cleanup;
+ pBtScanStart = (wlan_bt_coex_bt_scan_start_payload_type *)buf;
+ btScanStartVenData.scan_type = pBtScanStart->scan_type;
+ btScanStartVenData.scan_bitmap = pBtScanStart->scan_bitmap;
+
+ pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
+ sizeof(bt_coex_bt_scan_start_vendor_data_t),
+ (u8 *)&btScanStartVenData, pTlv);
+ tot_len += sizeof(tlv_log) +
+ sizeof(bt_coex_bt_scan_start_vendor_data_t);
+ } else if(id == EVENT_WLAN_BT_COEX_BT_SCAN_STOP) {
+ wlan_bt_coex_bt_scan_stop_payload_type *pBtScanStop;
+ bt_coex_bt_scan_stop_vendor_data_t btScanStopVenData;
+
+ pConnectEvent->event = WIFI_EVENT_BT_COEX_BT_SCAN_STOP;
+
+ pBtScanStop = (wlan_bt_coex_bt_scan_stop_payload_type *)buf;
+ btScanStopVenData.scan_type = pBtScanStop->scan_type;
+ btScanStopVenData.scan_bitmap = pBtScanStop->scan_bitmap;
+
+ pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
+ sizeof(bt_coex_bt_scan_stop_vendor_data_t),
+ (u8 *)&btScanStopVenData, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(bt_coex_bt_scan_stop_vendor_data_t);
+ }
+ status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
+ if (status != WIFI_SUCCESS) {
+ ALOGE("Failed to write bt_coex_scan event into ring buffer");
}
- memset(pWakeLockEvent, 0, len_wakelock_event);
+ return status;
+}
+static wifi_error process_bt_coex_event(hal_info *info, u32 id,
+ u8* buf, int length)
+{
+ wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
+ wifi_ring_buffer_entry *pRingBufferEntry;
+ tlv_log *pTlv;
+ int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
+ u8 out_buf[RING_BUF_ENTRY_SIZE];
+ u8 link_id, link_state, link_role, link_type = 0, Rsco = 0;
+ u16 Tsco = 0;
+ wifi_error status;
+ bt_coex_hid_vendor_data_t btCoexHidVenData;
+
+ pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
+ memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE);
+ pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
+ (pRingBufferEntry + 1);
+
+ switch (id) {
+ case EVENT_WLAN_BT_COEX_BT_SCO_START:
+ {
+ wlan_bt_coex_bt_sco_start_payload_type *pBtCoexStartPL;
+ pBtCoexStartPL = (wlan_bt_coex_bt_sco_start_payload_type *)buf;
+
+ link_id = pBtCoexStartPL->link_id;
+ link_state = pBtCoexStartPL->link_state;
+ link_role = pBtCoexStartPL->link_role;
+ link_type = pBtCoexStartPL->link_type;
+ Tsco = pBtCoexStartPL->Tsco;
+ Rsco = pBtCoexStartPL->Rsco;
+
+ pConnectEvent->event = WIFI_EVENT_BT_COEX_BT_SCO_START;
+ }
+ break;
+ case EVENT_WLAN_BT_COEX_BT_SCO_STOP:
+ {
+ wlan_bt_coex_bt_sco_stop_payload_type *pBtCoexStopPL;
+ pBtCoexStopPL = (wlan_bt_coex_bt_sco_stop_payload_type *)buf;
+
+ link_id = pBtCoexStopPL->link_id;
+ link_state = pBtCoexStopPL->link_state;
+ link_role = pBtCoexStopPL->link_role;
+ link_type = pBtCoexStopPL->link_type;
+ Tsco = pBtCoexStopPL->Tsco;
+ Rsco = pBtCoexStopPL->Rsco;
+
+ pConnectEvent->event = WIFI_EVENT_BT_COEX_BT_SCO_STOP;
+ }
+ break;
+ case EVENT_WIFI_BT_COEX_BT_HID_START:
+ {
+ wlan_bt_coex_bt_hid_start_payload_type *pBtCoexHidStartPL;
+ pBtCoexHidStartPL = (wlan_bt_coex_bt_hid_start_payload_type *)buf;
+
+ link_id = pBtCoexHidStartPL->link_id;
+ link_state = pBtCoexHidStartPL->link_state;
+ link_role = pBtCoexHidStartPL->link_role;
+ btCoexHidVenData.Tsniff = pBtCoexHidStartPL->Tsniff;
+ btCoexHidVenData.attempts = pBtCoexHidStartPL->attempts;
+
+ pConnectEvent->event = WIFI_EVENT_BT_COEX_BT_HID_START;
+ }
+ break;
+ case EVENT_WIFI_BT_COEX_BT_HID_STOP:
+ {
+ wlan_bt_coex_bt_hid_stop_payload_type *pBtCoexHidStopPL;
+ pBtCoexHidStopPL = (wlan_bt_coex_bt_hid_stop_payload_type *)buf;
+
+ link_id = pBtCoexHidStopPL->link_id;
+ link_state = pBtCoexHidStopPL->link_state;
+ link_role = pBtCoexHidStopPL->link_role;
+ btCoexHidVenData.Tsniff = pBtCoexHidStopPL->Tsniff;
+ btCoexHidVenData.attempts = pBtCoexHidStopPL->attempts;
+
+ pConnectEvent->event = WIFI_EVENT_BT_COEX_BT_HID_STOP;
+ }
+ break;
+ default:
+ return WIFI_SUCCESS;
+ }
+
+ pTlv = &pConnectEvent->tlvs[0];
+ pTlv = addLoggerTlv(WIFI_TAG_LINK_ID, sizeof(link_id), &link_id, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(link_id);
+
+ pTlv = addLoggerTlv(WIFI_TAG_LINK_ROLE, sizeof(link_role),
+ &link_role, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(link_role);
+
+ pTlv = addLoggerTlv(WIFI_TAG_LINK_STATE, sizeof(link_state),
+ &link_state, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(link_state);
+
+ if ((pConnectEvent->event == EVENT_WLAN_BT_COEX_BT_SCO_START) ||
+ (pConnectEvent->event == EVENT_WLAN_BT_COEX_BT_SCO_STOP)) {
+ pTlv = addLoggerTlv(WIFI_TAG_LINK_TYPE, sizeof(link_type),
+ &link_type, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(link_type);
+
+ pTlv = addLoggerTlv(WIFI_TAG_TSCO, sizeof(Tsco), (u8 *)&Tsco, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(Tsco);
+
+ pTlv = addLoggerTlv(WIFI_TAG_RSCO, sizeof(Rsco), &Rsco, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(Rsco);
+ } else if ((pConnectEvent->event == EVENT_WLAN_BT_COEX_BT_SCO_START) ||
+ (pConnectEvent->event == EVENT_WLAN_BT_COEX_BT_SCO_STOP)) {
+ pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
+ sizeof(bt_coex_hid_vendor_data_t),
+ (u8 *)&btCoexHidVenData, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(bt_coex_hid_vendor_data_t);
+ }
+
+ status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
+ if (status != WIFI_SUCCESS) {
+ ALOGE("Failed to write bt_coex_event into ring buffer");
+ }
+
+ return status;
+}
+
+static wifi_error process_extscan_event(hal_info *info, u32 id,
+ u8* buf, int length)
+{
+ wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
+ wifi_ring_buffer_entry *pRingBufferEntry;
+ tlv_log *pTlv;
+ int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
+ u8 out_buf[RING_BUF_ENTRY_SIZE];
+ wifi_error status;
+
+ pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
+ memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE);
+ pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
+ (pRingBufferEntry + 1);
+ pTlv = &pConnectEvent->tlvs[0];
+
+ switch (id) {
+ case EVENT_WLAN_EXTSCAN_CYCLE_STARTED:
+ {
+ ext_scan_cycle_vendor_data_t extScanCycleVenData;
+ wlan_ext_scan_cycle_started_payload_type *pExtScanCycleStarted;
+ pConnectEvent->event = WIFI_EVENT_G_SCAN_CYCLE_STARTED;
+ pExtScanCycleStarted =
+ (wlan_ext_scan_cycle_started_payload_type *)buf;
+ pTlv = addLoggerTlv(WIFI_TAG_SCAN_ID, sizeof(u32),
+ (u8 *)&pExtScanCycleStarted->scan_id, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(u32);
+
+ extScanCycleVenData.timer_tick = pExtScanCycleStarted->timer_tick;
+ extScanCycleVenData.scheduled_bucket_mask =
+ pExtScanCycleStarted->scheduled_bucket_mask;
+ extScanCycleVenData.scan_cycle_count =
+ pExtScanCycleStarted->scan_cycle_count;
+
+ pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
+ sizeof(ext_scan_cycle_vendor_data_t),
+ (u8 *)&extScanCycleVenData, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(ext_scan_cycle_vendor_data_t);
+ }
+ break;
+ case EVENT_WLAN_EXTSCAN_CYCLE_COMPLETED:
+ {
+ ext_scan_cycle_vendor_data_t extScanCycleVenData;
+ wlan_ext_scan_cycle_completed_payload_type *pExtScanCycleCompleted;
+ pConnectEvent->event = WIFI_EVENT_G_SCAN_CYCLE_COMPLETED;
+ pExtScanCycleCompleted =
+ (wlan_ext_scan_cycle_completed_payload_type *)buf;
+ pTlv = addLoggerTlv(WIFI_TAG_SCAN_ID, sizeof(u32),
+ (u8 *)&pExtScanCycleCompleted->scan_id, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(u32);
+
+ extScanCycleVenData.timer_tick = pExtScanCycleCompleted->timer_tick;
+ extScanCycleVenData.scheduled_bucket_mask =
+ pExtScanCycleCompleted->scheduled_bucket_mask;
+ extScanCycleVenData.scan_cycle_count =
+ pExtScanCycleCompleted->scan_cycle_count;
+
+ pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
+ sizeof(ext_scan_cycle_vendor_data_t),
+ (u8 *)&extScanCycleVenData, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(ext_scan_cycle_vendor_data_t);
+ }
+ break;
+ case EVENT_WLAN_EXTSCAN_BUCKET_STARTED:
+ {
+ wlan_ext_scan_bucket_started_payload_type *pExtScanBucketStarted;
+ u32 bucket_id;
+ pConnectEvent->event = WIFI_EVENT_G_SCAN_BUCKET_STARTED;
+ pExtScanBucketStarted =
+ (wlan_ext_scan_bucket_started_payload_type *)buf;
+ bucket_id = (u32)pExtScanBucketStarted->bucket_id;
+ pTlv = addLoggerTlv(WIFI_TAG_BUCKET_ID, sizeof(u32),
+ (u8 *)&bucket_id, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(u32);
+ }
+ break;
+ case EVENT_WLAN_EXTSCAN_BUCKET_COMPLETED:
+ {
+ wlan_ext_scan_bucket_completed_payload_type *pExtScanBucketCmpleted;
+ u32 bucket_id;
+ pConnectEvent->event = WIFI_EVENT_G_SCAN_BUCKET_COMPLETED;
+ pExtScanBucketCmpleted =
+ (wlan_ext_scan_bucket_completed_payload_type *)buf;
+ bucket_id = (u32)pExtScanBucketCmpleted->bucket_id;
+ pTlv = addLoggerTlv(WIFI_TAG_BUCKET_ID, sizeof(u32),
+ (u8 *)&bucket_id, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(u32);
+ }
+ break;
+ case EVENT_WLAN_EXTSCAN_FEATURE_STOP:
+ {
+ wlan_ext_scan_feature_stop_payload_type *pExtScanStop;
+ pConnectEvent->event = WIFI_EVENT_G_SCAN_STOP;
+ pExtScanStop = (wlan_ext_scan_feature_stop_payload_type *)buf;
+ pTlv = addLoggerTlv(WIFI_TAG_REQUEST_ID,
+ sizeof(wlan_ext_scan_feature_stop_payload_type),
+ (u8 *)&pExtScanStop, pTlv);
+ tot_len += sizeof(tlv_log) +
+ sizeof(wlan_ext_scan_feature_stop_payload_type);
+ }
+ break;
+ case EVENT_WLAN_EXTSCAN_RESULTS_AVAILABLE:
+ {
+ wlan_ext_scan_results_available_payload_type *pExtScanResultsAvail;
+ ext_scan_results_available_vendor_data_t extScanResultsAvailVenData;
+ u32 request_id;
+ pConnectEvent->event = WIFI_EVENT_G_SCAN_RESULTS_AVAILABLE;
+ pExtScanResultsAvail =
+ (wlan_ext_scan_results_available_payload_type *)buf;
+ request_id = pExtScanResultsAvail->request_id;
+ pTlv = addLoggerTlv(WIFI_TAG_REQUEST_ID, sizeof(u32),
+ (u8 *)&request_id, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(u32);
+
+ extScanResultsAvailVenData.table_type =
+ pExtScanResultsAvail->table_type;
+ extScanResultsAvailVenData.entries_in_use =
+ pExtScanResultsAvail->entries_in_use;
+ extScanResultsAvailVenData.maximum_entries =
+ pExtScanResultsAvail->maximum_entries;
+ extScanResultsAvailVenData.scan_count_after_getResults =
+ pExtScanResultsAvail->scan_count_after_getResults;
+ extScanResultsAvailVenData.threshold_num_scans =
+ pExtScanResultsAvail->threshold_num_scans;
+
+ pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
+ sizeof(ext_scan_results_available_vendor_data_t),
+ (u8 *)&extScanResultsAvailVenData, pTlv);
+ tot_len += sizeof(tlv_log) +
+ sizeof(ext_scan_results_available_vendor_data_t);
+ }
+ break;
+ }
+
+ status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
+ if (status != WIFI_SUCCESS) {
+ ALOGE("Failed to write ext_scan event into ring buffer");
+ }
+
+ return status;
+}
+
+static wifi_error process_addba_success_event(hal_info *info,
+ u8* buf, int length)
+{
+ wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
+ wifi_ring_buffer_entry *pRingBufferEntry;
+ tlv_log *pTlv;
+ int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
+ u8 out_buf[RING_BUF_ENTRY_SIZE];
+ wlan_add_block_ack_success_payload_type *pAddBASuccess;
+ addba_success_vendor_data_t addBASuccessVenData;
+ wifi_error status;
+
+ pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
+ memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE);
+ pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
+ (pRingBufferEntry + 1);
+ pAddBASuccess = (wlan_add_block_ack_success_payload_type *)buf;
+
+ addBASuccessVenData.ucBaTid = pAddBASuccess->ucBaTid;
+ addBASuccessVenData.ucBaBufferSize = pAddBASuccess->ucBaBufferSize;
+ addBASuccessVenData.ucBaSSN = pAddBASuccess->ucBaSSN;
+ addBASuccessVenData.fInitiator = pAddBASuccess->fInitiator;
+
+ pConnectEvent->event = WIFI_EVENT_BLOCK_ACK_NEGOTIATION_COMPLETE;
+ pTlv = &pConnectEvent->tlvs[0];
+ pTlv = addLoggerTlv(WIFI_TAG_ADDR, sizeof(pAddBASuccess->ucBaPeerMac),
+ (u8 *)pAddBASuccess->ucBaPeerMac, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(pAddBASuccess->ucBaPeerMac);
+
+ tot_len += add_status_tag(&pTlv, (int)ADDBA_SUCCESS);
+
+ pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
+ sizeof(addba_success_vendor_data_t),
+ (u8 *)&addBASuccessVenData, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(addba_success_vendor_data_t);
+
+ status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
+ if (status != WIFI_SUCCESS) {
+ ALOGE("Failed to write addba event into ring buffer");
+ }
+
+ return status;
+}
+
+static wifi_error process_addba_failed_event(hal_info *info,
+ u8* buf, int length)
+{
+ wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
+ wifi_ring_buffer_entry *pRingBufferEntry;
+ tlv_log *pTlv;
+ int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
+ u8 out_buf[RING_BUF_ENTRY_SIZE];
+ wlan_add_block_ack_failed_payload_type *pAddBAFailed;
+ addba_failed_vendor_data_t addBAFailedVenData;
+ wifi_error status;
+
+ pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
+ memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE);
+ pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
+ (pRingBufferEntry + 1);
+
+ addBAFailedVenData.ucBaTid = pAddBAFailed->ucBaTid;
+ addBAFailedVenData.fInitiator = pAddBAFailed->fInitiator;
+
+ pConnectEvent->event = WIFI_EVENT_BLOCK_ACK_NEGOTIATION_COMPLETE;
+ pTlv = &pConnectEvent->tlvs[0];
+ pTlv = addLoggerTlv(WIFI_TAG_ADDR, sizeof(pAddBAFailed->ucBaPeerMac),
+ (u8 *)pAddBAFailed->ucBaPeerMac, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(pAddBAFailed->ucBaPeerMac);
+
+ tot_len += add_status_tag(&pTlv, (int)ADDBA_FAILURE);
+
+ tot_len += add_reason_code_tag(&pTlv, (u16)pAddBAFailed->ucReasonCode);
+
+ pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
+ sizeof(addba_failed_vendor_data_t),
+ (u8 *)&pAddBAFailed, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(addba_failed_vendor_data_t);
+
+ status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
+ if (status != WIFI_SUCCESS) {
+ ALOGE("Failed to write addba event into ring buffer");
+ }
+
+ return status;
+}
+
+static wifi_error process_roam_event(hal_info *info, u32 id,
+ u8* buf, int length)
+{
+ wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
+ wifi_ring_buffer_entry *pRingBufferEntry;
+ tlv_log *pTlv;
+ int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
+ u8 out_buf[RING_BUF_ENTRY_SIZE];
+ wifi_error status;
+
+ pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
+ memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE);
+ pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
+ (pRingBufferEntry + 1);
+
+ switch (id)
+ {
+ case EVENT_WLAN_ROAM_SCAN_STARTED:
+ {
+ wlan_roam_scan_started_payload_type *pRoamScanStarted;
+ roam_scan_started_vendor_data_t roamScanStartedVenData;
+ pConnectEvent->event = WIFI_EVENT_ROAM_SCAN_STARTED;
+ pRoamScanStarted = (wlan_roam_scan_started_payload_type *)buf;
+ pTlv = &pConnectEvent->tlvs[0];
+ pTlv = addLoggerTlv(WIFI_TAG_SCAN_ID,
+ sizeof(pRoamScanStarted->scan_id),
+ (u8 *)&pRoamScanStarted->scan_id, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(pRoamScanStarted->scan_id);
+ roamScanStartedVenData.roam_scan_flags =
+ pRoamScanStarted->roam_scan_flags;
+ roamScanStartedVenData.cur_rssi = pRoamScanStarted->cur_rssi;
+ memcpy(roamScanStartedVenData.scan_params,
+ pRoamScanStarted->scan_params,
+ sizeof(roamScanStartedVenData.scan_params));
+ memcpy(roamScanStartedVenData.scan_channels,
+ pRoamScanStarted->scan_channels,
+ sizeof(roamScanStartedVenData.scan_channels));
+ pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
+ sizeof(roam_scan_started_vendor_data_t),
+ (u8 *)&roamScanStartedVenData, pTlv);
+ tot_len += sizeof(tlv_log) +
+ sizeof(roam_scan_started_vendor_data_t);
+ }
+ break;
+ case EVENT_WLAN_ROAM_SCAN_COMPLETE:
+ {
+ wlan_roam_scan_complete_payload_type *pRoamScanComplete;
+ roam_scan_complete_vendor_data_t roamScanCompleteVenData;
+ pConnectEvent->event = WIFI_EVENT_ROAM_SCAN_COMPLETE;
+ pRoamScanComplete = (wlan_roam_scan_complete_payload_type *)buf;
+ pTlv = &pConnectEvent->tlvs[0];
+
+ pTlv = addLoggerTlv(WIFI_TAG_SCAN_ID,
+ sizeof(pRoamScanComplete->scan_id),
+ (u8 *)&pRoamScanComplete->scan_id, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(pRoamScanComplete->scan_id);
+
+ roamScanCompleteVenData.reason = pRoamScanComplete->reason;
+ roamScanCompleteVenData.completion_flags =
+ pRoamScanComplete->completion_flags;
+ roamScanCompleteVenData.num_candidate =
+ pRoamScanComplete->num_candidate;
+ roamScanCompleteVenData.flags = pRoamScanComplete->flags;
+
+ pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
+ sizeof(roam_scan_complete_vendor_data_t),
+ (u8 *)&roamScanCompleteVenData, pTlv);
+ tot_len += sizeof(tlv_log) +
+ sizeof(roam_scan_complete_vendor_data_t);
+ }
+ break;
+ case EVENT_WLAN_ROAM_CANDIDATE_FOUND:
+ {
+ wlan_roam_candidate_found_payload_type *pRoamCandidateFound;
+ roam_candidate_found_vendor_data_t roamCandidateFoundVendata;
+ pConnectEvent->event = WIFI_EVENT_ROAM_CANDIDATE_FOUND;
+ pRoamCandidateFound = (wlan_roam_candidate_found_payload_type *)buf;
+ pTlv = &pConnectEvent->tlvs[0];
+ pTlv = addLoggerTlv(WIFI_TAG_CHANNEL,
+ sizeof(pRoamCandidateFound->channel),
+ (u8 *)&pRoamCandidateFound->channel, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(pRoamCandidateFound->channel);
+
+ pTlv = addLoggerTlv(WIFI_TAG_RSSI,
+ sizeof(pRoamCandidateFound->rssi),
+ (u8 *)&pRoamCandidateFound->rssi, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(pRoamCandidateFound->rssi);
+
+ pTlv = addLoggerTlv(WIFI_TAG_BSSID,
+ sizeof(pRoamCandidateFound->bssid),
+ (u8 *)pRoamCandidateFound->bssid, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(pRoamCandidateFound->bssid);
+
+ pTlv = addLoggerTlv(WIFI_TAG_SSID,
+ sizeof(pRoamCandidateFound->ssid),
+ (u8 *)pRoamCandidateFound->ssid, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(pRoamCandidateFound->ssid);
+
+ roamCandidateFoundVendata.auth_mode =
+ pRoamCandidateFound->auth_mode;
+ roamCandidateFoundVendata.ucast_cipher =
+ pRoamCandidateFound->ucast_cipher;
+ roamCandidateFoundVendata.mcast_cipher =
+ pRoamCandidateFound->mcast_cipher;
+ pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
+ sizeof(roam_candidate_found_vendor_data_t),
+ (u8 *)&roamCandidateFoundVendata, pTlv);
+ tot_len += sizeof(tlv_log) +
+ sizeof(roam_candidate_found_vendor_data_t);
+ }
+ break;
+ case EVENT_WLAN_ROAM_SCAN_CONFIG:
+ {
+ wlan_roam_scan_config_payload_type *pRoamScanConfig;
+ roam_scan_config_vendor_data_t roamScanConfigVenData;
+
+ pConnectEvent->event = WIFI_EVENT_ROAM_SCAN_CONFIG;
+ pRoamScanConfig = (wlan_roam_scan_config_payload_type *)buf;
+
+ pTlv = &pConnectEvent->tlvs[0];
+
+ roamScanConfigVenData.flags = pRoamScanConfig->flags;
+ memcpy(roamScanConfigVenData.roam_scan_config,
+ pRoamScanConfig->roam_scan_config,
+ sizeof(roamScanConfigVenData.roam_scan_config));
+
+ pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
+ sizeof(wlan_roam_scan_config_payload_type),
+ (u8 *)pRoamScanConfig, pTlv);
+ tot_len += sizeof(tlv_log) +
+ sizeof(wlan_roam_scan_config_payload_type);
+ }
+ break;
+ }
+
+ status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
+ if (status != WIFI_SUCCESS) {
+ ALOGE("Failed to write roam event into ring buffer");
+ }
+
+ return status;
+}
+
+static wifi_error process_fw_diag_msg(hal_info *info, u8* buf, u16 length)
+{
+ u16 count = 0, id, payloadlen;
+ wifi_error status;
+ fw_diag_msg_hdr_t *dmh;
+
+ buf += 4;
+ length -= 4;
+
+ while (length > (count + sizeof(fw_diag_msg_hdr_t))) {
+ dmh = (fw_diag_msg_hdr_t *)(buf + count);
+
+ id = dmh->diag_id;
+ payloadlen = dmh->payload_len;
+
+ switch (dmh->diag_event_type) {
+ case WLAN_DIAG_TYPE_EVENT:
+ {
+ switch (id) {
+ case EVENT_WLAN_BT_COEX_BT_SCO_START:
+ case EVENT_WLAN_BT_COEX_BT_SCO_STOP:
+ case EVENT_WIFI_BT_COEX_BT_HID_START:
+ case EVENT_WIFI_BT_COEX_BT_HID_STOP:
+ status = process_bt_coex_event(info, id, dmh->payload,
+ payloadlen);
+ if (status != WIFI_SUCCESS) {
+ ALOGE("Failed to process bt_coex event");
+ return status;
+ }
+ break;
+ case EVENT_WLAN_BT_COEX_BT_SCAN_START:
+ case EVENT_WLAN_BT_COEX_BT_SCAN_STOP:
+ status = process_bt_coex_scan_event(info, id,
+ dmh->payload,
+ payloadlen);
+ if (status != WIFI_SUCCESS) {
+ ALOGE("Failed to process bt_coex_scan event");
+ return status;
+ }
+ break;
+ case EVENT_WLAN_EXTSCAN_CYCLE_STARTED:
+ case EVENT_WLAN_EXTSCAN_CYCLE_COMPLETED:
+ case EVENT_WLAN_EXTSCAN_BUCKET_STARTED:
+ case EVENT_WLAN_EXTSCAN_BUCKET_COMPLETED:
+ case EVENT_WLAN_EXTSCAN_FEATURE_STOP:
+ case EVENT_WLAN_EXTSCAN_RESULTS_AVAILABLE:
+ status = process_extscan_event(info, id, dmh->payload,
+ payloadlen);
+ if (status != WIFI_SUCCESS) {
+ ALOGE("Failed to process extscan event");
+ return status;
+ }
+ break;
+ case EVENT_WLAN_ROAM_SCAN_STARTED:
+ case EVENT_WLAN_ROAM_SCAN_COMPLETE:
+ case EVENT_WLAN_ROAM_CANDIDATE_FOUND:
+ case EVENT_WLAN_ROAM_SCAN_CONFIG:
+ status = process_roam_event(info, id, dmh->payload,
+ payloadlen);
+ if (status != WIFI_SUCCESS) {
+ ALOGE("Failed to process roam event");
+ return status;
+ }
+ break;
+ case EVENT_WLAN_ADD_BLOCK_ACK_SUCCESS:
+ status = process_addba_success_event(info, dmh->payload,
+ payloadlen);
+ if (status != WIFI_SUCCESS) {
+ ALOGE("Failed to process addba success event");
+ return status;
+ }
+ break;
+ case EVENT_WLAN_ADD_BLOCK_ACK_FAILED:
+ status = process_addba_failed_event(info, dmh->payload,
+ payloadlen);
+ if (status != WIFI_SUCCESS) {
+ ALOGE("Failed to process addba failed event");
+ return status;
+ }
+ break;
+ default:
+ return WIFI_SUCCESS;
+ }
+ }
+ break;
+ case WLAN_DIAG_TYPE_LOG:
+ {
+ }
+ break;
+ case WLAN_DIAG_TYPE_MSG:
+ {
+ }
+ break;
+ default:
+ return WIFI_SUCCESS;
+ }
+ count += payloadlen + sizeof(fw_diag_msg_hdr_t);
+ }
+ return WIFI_SUCCESS;
+}
+
+static wifi_error remap_event(int in_event, int *out_event)
+{
+ int i = 0;
+ while (i < MAX_CONNECTIVITY_EVENTS) {
+ if (events[i].q_event == in_event) {
+ *out_event = events[i].g_event;
+ return WIFI_SUCCESS;
+ }
+ i++;
+ }
+ return WIFI_ERROR_UNKNOWN;
+}
+
+static wifi_error process_wlan_pe_event(hal_info *info, u8* buf, int length)
+{
+ wlan_pe_event_t *pWlanPeEvent;
+ pe_event_vendor_data_t peEventVenData;
+ wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
+ wifi_ring_buffer_entry *pRingBufferEntry;
+ tlv_log *pTlv;
+ int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
+ u8 out_buf[RING_BUF_ENTRY_SIZE];
+ wifi_error status;
+
+ pWlanPeEvent = (wlan_pe_event_t *)buf;
+
+ pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
+ memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE);
+ pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
+ (pRingBufferEntry + 1);
+
+ status = remap_event(pWlanPeEvent->event_type,
+ (int *)&pConnectEvent->event);
+ if (status != WIFI_SUCCESS)
+ return status;
+
+ pTlv = &pConnectEvent->tlvs[0];
+ pTlv = addLoggerTlv(WIFI_TAG_BSSID, sizeof(pWlanPeEvent->bssid),
+ (u8 *)pWlanPeEvent->bssid, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(pWlanPeEvent->bssid);
+
+ tot_len += add_status_tag(&pTlv, (int)pWlanPeEvent->status);
+
+ pTlv = addLoggerTlv(WIFI_TAG_REASON_CODE, sizeof(pWlanPeEvent->reason_code),
+ (u8 *)&pWlanPeEvent->reason_code, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(pWlanPeEvent->reason_code);
+
+ peEventVenData.sme_state = pWlanPeEvent->sme_state;
+ peEventVenData.mlm_state = pWlanPeEvent->mlm_state;
+
+ pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC,
+ sizeof(pe_event_vendor_data_t),
+ (u8 *)&peEventVenData, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(pe_event_vendor_data_t);
+
+ status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
+ if (status != WIFI_SUCCESS) {
+ ALOGE("Failed to write pe event into ring buffer");
+ }
+
+ return status;
+}
+
+static wifi_error process_wlan_eapol_event(hal_info *info, u8* buf, int length)
+{
+ wifi_ring_buffer_driver_connectivity_event *pConnectEvent;
+ wlan_eapol_event_t *pWlanEapolEvent;
+ wifi_ring_buffer_entry *pRingBufferEntry;
+ u8 out_buf[RING_BUF_ENTRY_SIZE];
+ int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event);
+ tlv_log *pTlv;
+ u32 eapol_msg_type = 0;
+ wifi_error status;
+
+ pWlanEapolEvent = (wlan_eapol_event_t *)buf;
+ pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0];
+ memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE);
+ pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *)
+ (pRingBufferEntry + 1);
+
+ if (pWlanEapolEvent->event_sub_type ==
+ WLAN_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED)
+ pConnectEvent->event = WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED;
+ else
+ pConnectEvent->event = WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED;
+
+ pTlv = &pConnectEvent->tlvs[0];
+
+ if ((pWlanEapolEvent->eapol_key_info & EAPOL_MASK) == EAPOL_M1_MASK)
+ eapol_msg_type = 1;
+ else if ((pWlanEapolEvent->eapol_key_info & EAPOL_MASK) == EAPOL_M2_MASK)
+ eapol_msg_type = 2;
+ else if ((pWlanEapolEvent->eapol_key_info & EAPOL_MASK) == EAPOL_M3_MASK)
+ eapol_msg_type = 3;
+ else if ((pWlanEapolEvent->eapol_key_info & EAPOL_MASK) == EAPOL_M4_MASK)
+ eapol_msg_type = 4;
+ else
+ ALOGI("Unknow EAPOL message type \n");
+ pTlv = addLoggerTlv(WIFI_TAG_EAPOL_MESSAGE_TYPE, sizeof(u32),
+ (u8 *)&eapol_msg_type, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(u32);
+ pTlv = addLoggerTlv(WIFI_TAG_ADDR1, sizeof(pWlanEapolEvent->dest_addr),
+ (u8 *)pWlanEapolEvent->dest_addr, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(pWlanEapolEvent->dest_addr);
+ pTlv = addLoggerTlv(WIFI_TAG_ADDR2, sizeof(pWlanEapolEvent->src_addr),
+ (u8 *)pWlanEapolEvent->src_addr, pTlv);
+ tot_len += sizeof(tlv_log) + sizeof(pWlanEapolEvent->src_addr);
+
+ status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len);
+ if (status != WIFI_SUCCESS) {
+ ALOGE("Failed to write eapol event into ring buffer");
+ }
+
+ return status;
+}
+
+static wifi_error process_wakelock_event(hal_info *info, u8* buf, int length)
+{
+ wlan_wake_lock_event_t *pWlanWakeLockEvent;
+ wake_lock_event *pWakeLockEvent;
+ wifi_power_event *pPowerEvent;
+ tlv_log *pTlv;
+ wifi_ring_buffer_entry *pRingBufferEntry;
+ u16 len_ring_buffer_entry;
+ struct timeval time;
+ wifi_error status;
+ u8 wl_ring_buffer[RING_BUF_ENTRY_SIZE];
+ u16 entry_size;
+
+ pWlanWakeLockEvent = (wlan_wake_lock_event_t *)(buf);
+ entry_size = sizeof(wifi_power_event) +
+ sizeof(tlv_log) +
+ sizeof(wake_lock_event) +
+ pWlanWakeLockEvent->name_len + 1;
+ len_ring_buffer_entry = sizeof(wifi_ring_buffer_entry) + entry_size;
+
+ if (len_ring_buffer_entry > RING_BUF_ENTRY_SIZE) {
+ pRingBufferEntry = (wifi_ring_buffer_entry *)malloc(
+ len_ring_buffer_entry);
+ if (pRingBufferEntry == NULL) {
+ ALOGE("%s: Failed to allocate memory", __FUNCTION__);
+ return WIFI_ERROR_OUT_OF_MEMORY;
+ }
+ } else {
+ pRingBufferEntry = (wifi_ring_buffer_entry *)wl_ring_buffer;
+ }
+
+ pPowerEvent = (wifi_power_event *)(pRingBufferEntry + 1);
+ pPowerEvent->event = WIFI_TAG_WAKE_LOCK_EVENT;
+
+ pTlv = &pPowerEvent->tlvs[0];
+ pTlv->tag = WIFI_TAG_WAKE_LOCK_EVENT;
+ pTlv->length = sizeof(wake_lock_event) +
+ pWlanWakeLockEvent->name_len + 1;
+
+ pWakeLockEvent = (wake_lock_event *)pTlv->value;
pWakeLockEvent->status = pWlanWakeLockEvent->status;
pWakeLockEvent->reason = pWlanWakeLockEvent->reason;
memcpy(pWakeLockEvent->name, pWlanWakeLockEvent->name,
pWlanWakeLockEvent->name_len);
- len_power_event = sizeof(wifi_power_event) +
- sizeof(tlv_log) + len_wakelock_event;
- pPowerEvent = (wifi_power_event *)malloc(len_power_event);
- if (pPowerEvent == NULL) {
- ALOGE("%s: Failed to allocate memory", __func__);
- goto cleanup;
- }
-
- memset(pPowerEvent, 0, len_power_event);
- pPowerEvent->event = WIFI_TAG_WAKE_LOCK_EVENT;
-
- pTlv = &pPowerEvent->tlvs[0];
- addLoggerTlv(WIFI_TAG_WAKE_LOCK_EVENT, len_wakelock_event,
- (u8*)pWakeLockEvent, pTlv);
- len_ring_buffer_entry = sizeof(wifi_ring_buffer_entry) + len_power_event;
- pRingBufferEntry = (wifi_ring_buffer_entry *)malloc(
- len_ring_buffer_entry);
- if (pRingBufferEntry == NULL) {
- ALOGE("%s: Failed to allocate memory", __func__);
- goto cleanup;
- }
- memset(pRingBufferEntry, 0, len_ring_buffer_entry);
-
- pRingBufferEntry->entry_size = len_power_event;
- pRingBufferEntry->flags = 0;
+ pRingBufferEntry->entry_size = entry_size;
+ pRingBufferEntry->flags = RING_BUFFER_ENTRY_FLAGS_HAS_BINARY |
+ RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP;
pRingBufferEntry->type = ENTRY_TYPE_POWER_EVENT;
- pRingBufferEntry->timestamp = 0;
+ gettimeofday(&time, NULL);
+ pRingBufferEntry->timestamp = time.tv_usec + time.tv_sec * 1000 * 1000;
- memcpy(pRingBufferEntry + 1, pPowerEvent, len_power_event);
- ALOGI("Ring buffer Length %d \n", len_ring_buffer_entry);
-
- // Write if verbose and handler is set
- num_records = 1;
+ /* Write if verbose and handler is set */
if (info->rb_infos[POWER_EVENTS_RB_ID].verbose_level >= 1 &&
info->on_ring_buffer_data)
- ring_buffer_write(&info->rb_infos[POWER_EVENTS_RB_ID],
- (u8*)pRingBufferEntry, len_ring_buffer_entry, num_records);
- else
- ALOGI("Verbose level not set \n");
-cleanup:
- if (pWakeLockEvent)
- free(pWakeLockEvent);
- if (pPowerEvent)
- free(pPowerEvent);
- if (pRingBufferEntry)
+ status = ring_buffer_write(&info->rb_infos[POWER_EVENTS_RB_ID],
+ (u8*)pRingBufferEntry,
+ len_ring_buffer_entry, 1);
+
+ if ((u8 *)pRingBufferEntry != wl_ring_buffer) {
+ ALOGI("Message with more than RING_BUF_ENTRY_SIZE");
free(pRingBufferEntry);
- return ret;
+ }
+
+ return status;
}
-int diag_message_handler(hal_info *info, nl_msg *msg)
+static void process_wlan_log_complete_event(hal_info *info,
+ u8* buf,
+ int length)
+{
+ wlan_log_complete_event_t *lfd_event;
+
+ ALOGV("Received log completion event from driver");
+ lfd_event = (wlan_log_complete_event_t *)buf;
+
+ push_out_all_ring_buffers(info);
+
+ if (lfd_event->is_fatal == WLAN_LOG_TYPE_FATAL) {
+ ALOGE("Received fatal event, sending alert");
+ send_alert(info, lfd_event->reason_code);
+ }
+}
+
+static wifi_error update_stats_to_ring_buf(hal_info *info,
+ u8 *rb_entry, u32 size)
+{
+ int num_records = 1;
+ wifi_ring_buffer_entry *pRingBufferEntry =
+ (wifi_ring_buffer_entry *)rb_entry;
+ struct timeval time;
+
+ pRingBufferEntry->entry_size = size - sizeof(wifi_ring_buffer_entry);
+ pRingBufferEntry->flags = RING_BUFFER_ENTRY_FLAGS_HAS_BINARY |
+ RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP;
+ pRingBufferEntry->type = ENTRY_TYPE_PKT;
+ gettimeofday(&time,NULL);
+ pRingBufferEntry->timestamp = time.tv_usec + time.tv_sec * 1000 * 1000;
+
+ // Write if verbose and handler is set
+ if ((info->rb_infos[PKT_STATS_RB_ID].verbose_level >= VERBOSE_DEBUG_PROBLEM)
+ && info->on_ring_buffer_data)
+ ring_buffer_write(&info->rb_infos[PKT_STATS_RB_ID],
+ (u8*)pRingBufferEntry,
+ size,
+ num_records);
+
+ return WIFI_SUCCESS;
+}
+
+static u16 get_rate(u16 mcs_r, u8 short_gi)
+{
+ u16 tx_rate = 0;
+ MCS mcs;
+ static u16 rate_lookup[][8] = {{96, 48, 24, 12, 108, 72, 36, 18},
+ {22, 11, 4, 2, 22, 11, 4, 0}};
+ static u16 MCS_rate_lookup_ht[][8] =
+ {{ 13, 14, 27, 30, 59, 65, 117, 130},
+ { 26, 29, 54, 60, 117, 130, 234, 260},
+ { 39, 43, 81, 90, 176, 195, 351, 390},
+ { 52, 58, 108, 120, 234, 260, 468, 520},
+ { 78, 87, 162, 180, 351, 390, 702, 780},
+ {104, 116, 216, 240, 468, 520, 936, 1040},
+ {117, 130, 243, 270, 527, 585, 1053, 1170},
+ {130, 144, 270, 300, 585, 650, 1170, 1300},
+ {156, 173, 324, 360, 702, 780, 1404, 1560},
+ { 0, 0, 360, 400, 780, 867, 1560, 1733},
+ { 26, 29, 54, 60, 117, 130, 234, 260},
+ { 52, 58, 108, 120, 234, 260, 468, 520},
+ { 78, 87, 162, 180, 351, 390, 702, 780},
+ {104, 116, 216, 240, 468, 520, 936, 1040},
+ {156, 173, 324, 360, 702, 780, 1404, 1560},
+ {208, 231, 432, 480, 936,1040, 1872, 2080},
+ {234, 261, 486, 540,1053,1170, 2106, 2340},
+ {260, 289, 540, 600,1170,1300, 2340, 2600},
+ {312, 347, 648, 720,1404,1560, 2808, 3120},
+ { 0, 0, 720, 800,1560,1733, 3120, 3467}};
+
+ mcs.mcs = mcs_r;
+ if ((mcs.mcs_s.preamble < 4) && (mcs.mcs_s.rate < 10)) {
+ switch(mcs.mcs_s.preamble)
+ {
+ case 0:
+ case 1:
+ if(mcs.mcs_s.rate<8) {
+ tx_rate = rate_lookup [mcs.mcs_s.preamble][mcs.mcs_s.rate];
+ if (mcs.mcs_s.nss)
+ tx_rate *=2;
+ } else {
+ ALOGE("Unexpected rate value");
+ }
+ break;
+ case 2:
+ if(mcs.mcs_s.rate<8) {
+ if (!mcs.mcs_s.nss)
+ tx_rate = MCS_rate_lookup_ht[mcs.mcs_s.rate]
+ [2*mcs.mcs_s.bw+short_gi];
+ else
+ tx_rate = MCS_rate_lookup_ht[10+mcs.mcs_s.rate]
+ [2*mcs.mcs_s.bw+short_gi];
+ } else {
+ ALOGE("Unexpected HT mcs.mcs_s index");
+ }
+ break;
+ case 3:
+ if (!mcs.mcs_s.nss)
+ tx_rate = MCS_rate_lookup_ht[mcs.mcs_s.rate]
+ [2*mcs.mcs_s.bw+short_gi];
+ else
+ tx_rate = MCS_rate_lookup_ht[10+mcs.mcs_s.rate]
+ [2*mcs.mcs_s.bw+short_gi];
+ break;
+ default:
+ ALOGE("Unexpected preamble");
+ }
+ }
+ return tx_rate;
+}
+
+static u16 get_rx_rate(u16 mcs)
+{
+ /* TODO: guard interval is not specified currently */
+ return get_rate(mcs, 0);
+}
+
+static wifi_error parse_rx_stats(hal_info *info, u8 *buf, u16 size)
+{
+ wifi_error status;
+ rb_pkt_stats_t *rx_stats_rcvd = (rb_pkt_stats_t *)buf;
+ u8 rb_pkt_entry_buf[RING_BUF_ENTRY_SIZE];
+ wifi_ring_buffer_entry *pRingBufferEntry;
+ u32 len_ring_buffer_entry = 0;
+
+ len_ring_buffer_entry = sizeof(wifi_ring_buffer_entry)
+ + sizeof(wifi_ring_per_packet_status_entry)
+ + RX_HTT_HDR_STATUS_LEN;
+
+ if (len_ring_buffer_entry > RING_BUF_ENTRY_SIZE) {
+ pRingBufferEntry = (wifi_ring_buffer_entry *)malloc(
+ len_ring_buffer_entry);
+ if (pRingBufferEntry == NULL) {
+ ALOGE("%s: Failed to allocate memory", __FUNCTION__);
+ return WIFI_ERROR_OUT_OF_MEMORY;
+ }
+ } else {
+ pRingBufferEntry = (wifi_ring_buffer_entry *)rb_pkt_entry_buf;
+ }
+
+ wifi_ring_per_packet_status_entry *rb_pkt_stats =
+ (wifi_ring_per_packet_status_entry *)(pRingBufferEntry + 1);
+
+ if (size != sizeof(rb_pkt_stats_t)) {
+ ALOGE("%s Unexpected rx stats event length: %d", __FUNCTION__, size);
+ return WIFI_ERROR_UNKNOWN;
+ }
+
+ 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.tkip_mic_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;
+
+ rb_pkt_stats->tid = rx_stats_rcvd->mpdu_start.tid;
+
+ if (rx_stats_rcvd->ppdu_start.preamble_type == PREAMBLE_L_SIG_RATE) {
+ if (!rx_stats_rcvd->ppdu_start.l_sig_rate_select)
+ rb_pkt_stats->MCS |= 1 << 6;
+ rb_pkt_stats->MCS |= rx_stats_rcvd->ppdu_start.l_sig_rate % 8;
+ /*BW is 0 for legacy cases*/
+ } else if (rx_stats_rcvd->ppdu_start.preamble_type ==
+ PREAMBLE_VHT_SIG_A_1) {
+ rb_pkt_stats->MCS |= 2 << 6;
+ rb_pkt_stats->MCS |=
+ (rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_1 & BITMASK(7)) %8;
+ rb_pkt_stats->MCS |=
+ ((rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_1 >> 7) & 1) << 8;
+ } else if (rx_stats_rcvd->ppdu_start.preamble_type ==
+ PREAMBLE_VHT_SIG_A_2) {
+ rb_pkt_stats->MCS |= 3 << 6;
+ rb_pkt_stats->MCS |=
+ (rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_2 >> 4) & BITMASK(4);
+ rb_pkt_stats->MCS |=
+ (rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_1 & 3) << 8;
+ }
+ rb_pkt_stats->last_transmit_rate = get_rx_rate(rb_pkt_stats->MCS);
+
+ rb_pkt_stats->rssi = rx_stats_rcvd->ppdu_start.rssi_comb;
+ rb_pkt_stats->link_layer_transmit_sequence
+ = rx_stats_rcvd->mpdu_start.seq_num;
+
+ rb_pkt_stats->firmware_entry_timestamp
+ = rx_stats_rcvd->ppdu_end.wb_timestamp;
+
+ memcpy(&rb_pkt_stats->data[0], &rx_stats_rcvd->rx_hdr_status[0],
+ RX_HTT_HDR_STATUS_LEN);
+
+ status = update_stats_to_ring_buf(info, (u8 *)pRingBufferEntry,
+ len_ring_buffer_entry);
+
+ if (status != WIFI_SUCCESS) {
+ ALOGE("Failed to write Rx stats into the ring buffer");
+ }
+
+ if ((u8 *)pRingBufferEntry != rb_pkt_entry_buf) {
+ ALOGI("Message with more than RING_BUF_ENTRY_SIZE");
+ free (pRingBufferEntry);
+ }
+
+ return status;
+}
+
+static void parse_tx_rate_and_mcs(struct tx_ppdu_start *ppdu_start,
+ wifi_ring_per_packet_status_entry *rb_pkt_stats)
+{
+ u16 tx_rate = 0, short_gi = 0;
+ MCS mcs;
+
+ if (ppdu_start->valid_s0_bw20) {
+ short_gi = ppdu_start->s0_bw20.short_gi;
+ mcs.mcs_s.rate = ppdu_start->s0_bw20.rate;
+ mcs.mcs_s.nss = ppdu_start->s0_bw20.nss;
+ mcs.mcs_s.preamble = ppdu_start->s0_bw20.preamble_type;
+ mcs.mcs_s.bw = BW_20_MHZ;
+ } else if (ppdu_start->valid_s0_bw40) {
+ short_gi = ppdu_start->s0_bw40.short_gi;
+ mcs.mcs_s.rate = ppdu_start->s0_bw40.rate;
+ mcs.mcs_s.nss = ppdu_start->s0_bw40.nss;
+ mcs.mcs_s.preamble = ppdu_start->s0_bw40.preamble_type;
+ mcs.mcs_s.bw = BW_40_MHZ;
+ } else if (ppdu_start->valid_s0_bw80) {
+ short_gi = ppdu_start->s0_bw80.short_gi;
+ mcs.mcs_s.rate = ppdu_start->s0_bw80.rate;
+ mcs.mcs_s.nss = ppdu_start->s0_bw80.nss;
+ mcs.mcs_s.preamble = ppdu_start->s0_bw80.preamble_type;
+ mcs.mcs_s.bw = BW_80_MHZ;
+ } else if (ppdu_start->valid_s0_bw160) {
+ short_gi = ppdu_start->s0_bw160.short_gi;
+ mcs.mcs_s.rate = ppdu_start->s0_bw160.rate;
+ mcs.mcs_s.nss = ppdu_start->s0_bw160.nss;
+ mcs.mcs_s.preamble = ppdu_start->s0_bw160.preamble_type;
+ mcs.mcs_s.bw = BW_160_MHZ;
+ } else if (ppdu_start->valid_s1_bw20) {
+ short_gi = ppdu_start->s1_bw20.short_gi;
+ mcs.mcs_s.rate = ppdu_start->s1_bw20.rate;
+ mcs.mcs_s.nss = ppdu_start->s1_bw20.nss;
+ mcs.mcs_s.preamble = ppdu_start->s1_bw20.preamble_type;
+ mcs.mcs_s.bw = BW_20_MHZ;
+ } else if (ppdu_start->valid_s1_bw40) {
+ short_gi = ppdu_start->s1_bw40.short_gi;
+ mcs.mcs_s.rate = ppdu_start->s1_bw40.rate;
+ mcs.mcs_s.nss = ppdu_start->s1_bw40.nss;
+ mcs.mcs_s.preamble = ppdu_start->s1_bw40.preamble_type;
+ mcs.mcs_s.bw = BW_40_MHZ;
+ } else if (ppdu_start->valid_s1_bw80) {
+ short_gi = ppdu_start->s1_bw80.short_gi;
+ mcs.mcs_s.rate = ppdu_start->s1_bw80.rate;
+ mcs.mcs_s.nss = ppdu_start->s1_bw80.nss;
+ mcs.mcs_s.preamble = ppdu_start->s1_bw80.preamble_type;
+ mcs.mcs_s.bw = BW_80_MHZ;
+ } else if (ppdu_start->valid_s1_bw160) {
+ short_gi = ppdu_start->s1_bw160.short_gi;
+ mcs.mcs_s.rate = ppdu_start->s1_bw160.rate;
+ mcs.mcs_s.nss = ppdu_start->s1_bw160.nss;
+ mcs.mcs_s.preamble = ppdu_start->s1_bw160.preamble_type;
+ mcs.mcs_s.bw = BW_160_MHZ;
+ }
+
+ rb_pkt_stats->MCS = mcs.mcs;
+ rb_pkt_stats->last_transmit_rate = get_rate(mcs.mcs, short_gi);
+}
+
+static wifi_error parse_tx_stats(hal_info *info, void *buf,
+ u32 buflen, u8 logtype)
+{
+ wifi_error status;
+ 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);
+
+ ALOGV("Received Tx stats: log_type : %d", logtype);
+ switch (logtype)
+ {
+ case PKTLOG_TYPE_TX_CTRL:
+ {
+ if (buflen != sizeof (wh_pktlog_txctl)) {
+ ALOGE("Unexpected tx_ctrl event length: %d", buflen);
+ return WIFI_ERROR_UNKNOWN;
+ }
+
+ wh_pktlog_txctl *stats = (wh_pktlog_txctl *)buf;
+ struct tx_ppdu_start *ppdu_start =
+ (struct tx_ppdu_start *)(&stats->u.ppdu_start);
+
+ if (ppdu_start->frame_control & BIT(DATA_PROTECTED))
+ rb_pkt_stats->flags |=
+ PER_PACKET_ENTRY_FLAGS_PROTECTED;
+ rb_pkt_stats->link_layer_transmit_sequence
+ = ppdu_start->start_seq_num;
+ rb_pkt_stats->tid = ppdu_start->qos_ctl & 0xF;
+ parse_tx_rate_and_mcs(ppdu_start, rb_pkt_stats);
+ info->pkt_stats->tx_stats_events |= BIT(PKTLOG_TYPE_TX_CTRL);
+ }
+ break;
+ case PKTLOG_TYPE_TX_STAT:
+ {
+ if (buflen != sizeof(struct tx_ppdu_end)) {
+ ALOGE("Unexpected tx_stat event length: %d", buflen);
+ return WIFI_ERROR_UNKNOWN;
+ }
+
+ /* This should be the first event for tx-stats: So,
+ * previous stats are invalid. Flush the old stats and treat
+ * this as new packet
+ */
+ if (info->pkt_stats->tx_stats_events)
+ memset(rb_pkt_stats, 0,
+ sizeof(wifi_ring_per_packet_status_entry));
+
+ struct tx_ppdu_end *tx_ppdu_end = (struct tx_ppdu_end*)(buf);
+
+ if (tx_ppdu_end->stat.tx_ok)
+ rb_pkt_stats->flags |=
+ PER_PACKET_ENTRY_FLAGS_TX_SUCCESS;
+ rb_pkt_stats->transmit_success_timestamp =
+ tx_ppdu_end->try_list.try_00.timestamp;
+ rb_pkt_stats->rssi = tx_ppdu_end->stat.ack_rssi_ave;
+ rb_pkt_stats->num_retries =
+ tx_ppdu_end->stat.total_tries;
+
+ info->pkt_stats->tx_stats_events = BIT(PKTLOG_TYPE_TX_STAT);
+ }
+ break;
+ case PKTLOG_TYPE_RC_UPDATE:
+ case PKTLOG_TYPE_TX_MSDU_ID:
+ case PKTLOG_TYPE_TX_FRM_HDR:
+ case PKTLOG_TYPE_RC_FIND:
+ case PKTLOG_TYPE_TX_VIRT_ADDR:
+ ALOGV("%s : Unsupported log_type received : %d",
+ __FUNCTION__, logtype);
+ break;
+ default:
+ {
+ ALOGV("%s : Unexpected log_type received : %d",
+ __FUNCTION__, logtype);
+ return WIFI_ERROR_UNKNOWN;
+ }
+ }
+
+ if ((info->pkt_stats->tx_stats_events & BIT(PKTLOG_TYPE_TX_CTRL))&&
+ (info->pkt_stats->tx_stats_events & BIT(PKTLOG_TYPE_TX_STAT))) {
+ /* No tx payload as of now, add the length to parameter size(3rd)
+ * if there is any payload
+ */
+ status = update_stats_to_ring_buf(info,
+ (u8 *)pRingBufferEntry,
+ sizeof(wifi_ring_buffer_entry) +
+ sizeof(wifi_ring_per_packet_status_entry));
+
+ /* Flush the local copy after writing the stats to ring buffer
+ * for tx-stats.
+ */
+ info->pkt_stats->tx_stats_events = 0;
+ memset(rb_pkt_stats, 0,
+ sizeof(wifi_ring_per_packet_status_entry));
+
+ if (status != WIFI_SUCCESS) {
+ ALOGE("Failed to write into the ring buffer: %d", logtype);
+ return status;
+ }
+ }
+
+ return WIFI_SUCCESS;
+}
+
+static wifi_error parse_stats_record(hal_info *info, u8 *buf, u16 record_type,
+ u16 record_len)
+{
+ wifi_error status;
+ if (record_type == PKTLOG_TYPE_RX_STAT) {
+ status = parse_rx_stats(info, buf, record_len);
+ } else {
+ status = parse_tx_stats(info, buf, record_len, record_type);
+ }
+ return status;
+}
+
+static wifi_error parse_stats(hal_info *info, u8 *data, u32 buflen)
+{
+ wh_pktlog_hdr_t *pkt_stats_header;
+ wifi_error status = WIFI_SUCCESS;
+
+ do {
+ if (buflen < sizeof(wh_pktlog_hdr_t)) {
+ status = WIFI_ERROR_INVALID_ARGS;
+ break;
+ }
+
+ pkt_stats_header = (wh_pktlog_hdr_t *)data;
+
+ if (buflen < (sizeof(wh_pktlog_hdr_t) + pkt_stats_header->size)) {
+ status = WIFI_ERROR_INVALID_ARGS;
+ break;
+ }
+ status = parse_stats_record(info,
+ (u8 *)(pkt_stats_header + 1),
+ pkt_stats_header->log_type,
+ pkt_stats_header->size);
+ if (status != WIFI_SUCCESS) {
+ ALOGE("Failed to parse the stats type : %d",
+ pkt_stats_header->log_type);
+ return status;
+ }
+ data += (sizeof(wh_pktlog_hdr_t) + pkt_stats_header->size);
+ buflen -= (sizeof(wh_pktlog_hdr_t) + pkt_stats_header->size);
+ } while (buflen > 0);
+
+ return status;
+}
+
+wifi_error diag_message_handler(hal_info *info, nl_msg *msg)
{
tAniNlHdr *wnl = (tAniNlHdr *)nlmsg_hdr(msg);
u8 *buf;
-
- ALOGD("event sub type = %x", wnl->wmsg.type);
-
+ wifi_error status;
if (wnl->wmsg.type == ANI_NL_MSG_LOG_HOST_EVENT_LOG_TYPE) {
uint32_t diag_host_type;
buf = (uint8_t *)(wnl + 1);
diag_host_type = *(uint32_t *)(buf);
- ALOGD("diag type = %d", diag_host_type);
+ ALOGV("diag type = %d", diag_host_type);
+ buf += sizeof(uint32_t); //diag_type
if (diag_host_type == DIAG_TYPE_HOST_EVENTS) {
- buf += sizeof(uint32_t); //diag_type
host_event_hdr_t *event_hdr =
(host_event_hdr_t *)(buf);
- ALOGD("diag event_id = %d length %d",
+ ALOGV("diag event_id = %d length %d",
event_hdr->event_id, event_hdr->length);
buf += sizeof(host_event_hdr_t);
switch (event_hdr->event_id) {
case EVENT_WLAN_WAKE_LOCK:
process_wakelock_event(info, buf, event_hdr->length);
break;
- default:
- ALOGD("Unsupported Event %d \n", event_hdr->event_id);
+ case EVENT_WLAN_PE:
+ process_wlan_pe_event(info, buf, event_hdr->length);
break;
+ case EVENT_WLAN_EAPOL:
+ process_wlan_eapol_event(info, buf, event_hdr->length);
+ break;
+ case EVENT_WLAN_LOG_COMPLETE:
+ process_wlan_log_complete_event(info, buf, event_hdr->length);
+ break;
+ default:
+ return WIFI_SUCCESS;
+ }
+ } else if (diag_host_type == DIAG_TYPE_HOST_LOG_MSGS) {
+ drv_msg_t *drv_msg = (drv_msg_t *) (buf);
+ ALOGV("diag event_type = %0x length = %d",
+ drv_msg->event_type, drv_msg->length);
+ if (drv_msg->event_type == WLAN_PKT_LOG_STATS) {
+ if ((info->pkt_stats->prev_seq_no + 1) !=
+ drv_msg->u.pkt_stats_event.msg_seq_no) {
+ ALOGE("Few pkt stats messages missed: rcvd = %d, prev = %d",
+ drv_msg->u.pkt_stats_event.msg_seq_no,
+ info->pkt_stats->prev_seq_no);
+ if (info->pkt_stats->tx_stats_events) {
+ info->pkt_stats->tx_stats_events = 0;
+ memset(&info->pkt_stats->tx_stats, 0,
+ sizeof(wifi_ring_per_packet_status_entry));
+ }
+ }
+
+ info->pkt_stats->prev_seq_no =
+ drv_msg->u.pkt_stats_event.msg_seq_no;
+ status = parse_stats(info,
+ drv_msg->u.pkt_stats_event.payload,
+ drv_msg->u.pkt_stats_event.payload_len);
+ if (status != WIFI_SUCCESS) {
+ ALOGE("%s: Failed to parse Tx-Rx stats", __FUNCTION__);
+ ALOGE("Received msg Seq_num : %d",
+ drv_msg->u.pkt_stats_event.msg_seq_no);
+ hexdump((char *)drv_msg->u.pkt_stats_event.payload,
+ drv_msg->u.pkt_stats_event.payload_len);
+ return status;
+ }
}
}
- }
+ } else {
+ uint16_t diag_fw_type;
+ uint32_t event_id;
+ buf = (uint8_t *)NLMSG_DATA(wnl);
-// hexdump((char *)nlmsg_data(nlhdr), nlhdr->nlmsg_len);
- return NL_OK;
+ fw_event_hdr_t *event_hdr =
+ (fw_event_hdr_t *)(buf);
+ diag_fw_type = event_hdr->diag_type;
+ if (diag_fw_type == DIAG_TYPE_FW_MSG) {
+ dbglog_slot *slot;
+ u16 length = 0;
+ u32 version = 0;
+
+ slot = (dbglog_slot *)buf;
+ length = get_le32((u8 *)&slot->length);
+ process_fw_diag_msg(info, &slot->payload[0], length);
+ }
+ }
+ return WIFI_SUCCESS;
}
diff --git a/qcwcn/wifi_hal/wifilogger_diag.h b/qcwcn/wifi_hal/wifilogger_diag.h
index d59863c..9597b68 100644
--- a/qcwcn/wifi_hal/wifilogger_diag.h
+++ b/qcwcn/wifi_hal/wifilogger_diag.h
@@ -31,39 +31,75 @@
#include "common.h"
#include "wifi_hal.h"
+#include "wifilogger_event_defs.h"
#include <netlink/genl/genl.h>
#include <netlink/genl/family.h>
#include <netlink/genl/ctrl.h>
#include <linux/rtnetlink.h>
-#define ANI_NL_MSG_LOG_REG_TYPE 0x0001
#define ANI_NL_MSG_BASE 0x10 /* Some arbitrary base */
#define WIFI_HAL_USER_SOCK_PORT 646
#define WLAN_NL_MSG_CNSS_HOST_EVENT_LOG 17
#define ANI_NL_MSG_LOG_HOST_EVENT_LOG_TYPE 0x5050
-#define EVENT_WLAN_WAKE_LOCK 0xAA2 /* 96 bytes payload */
+#define WLAN_PKT_LOG_STATS 0x18E0
+
+/*
+ * - verbose_level 0 corresponds to no collection
+ * - verbose_level 1 correspond to normal log level, with minimal user impact.
+ * this is the default value
+ * - verbose_level 2 are enabled when user is lazily trying to reproduce a
+ problem, wifi performances and power
+ * can be impacted but device should not otherwise be significantly impacted
+ * - verbose_level 3+ are used when trying to actively debug a problem
+ */
+
+enum wifilogger_verbose_level {
+ VERBOSE_NO_COLLECTION,
+ VERBOSE_NORMAL_LOG,
+ VERBOSE_REPRO_PROBLEM,
+ VERBOSE_DEBUG_PROBLEM
+};
enum wifilogger_fw_diag_type {
DIAG_TYPE_FW_EVENT, /* send fw event- to diag*/
DIAG_TYPE_FW_LOG, /* send log event- to diag*/
DIAG_TYPE_FW_DEBUG_MSG, /* send dbg message- to diag*/
+ DIAG_TYPE_FW_MSG = 4, /* send fw message- to diag*/
};
enum wifilogger_host_diag_type {
- DIAG_TYPE_HOST_MSGS=1,
+ DIAG_TYPE_HOST_LOG_MSGS=1,
DIAG_TYPE_HOST_EVENTS=2,
};
-struct dbglog_slot {
- unsigned int diag_type;
- unsigned int timestamp;
- unsigned int length;
- unsigned int dropped;
+enum wlan_diag_frame_type {
+ WLAN_DIAG_TYPE_CONFIG,
+ WLAN_DIAG_TYPE_EVENT,
+ WLAN_DIAG_TYPE_LOG,
+ WLAN_DIAG_TYPE_MSG,
+ WLAN_DIAG_TYPE_LEGACY_MSG,
+};
+
+static uint32_t get_le32(const uint8_t *pos)
+{
+ return pos[0] | (pos[1] << 8) | (pos[2] << 16) | (pos[3] << 24);
+}
+
+typedef struct event_remap {
+ int q_event;
+ int g_event;
+} event_remap_t;
+
+typedef struct {
+ u32 diag_type;
+ u32 timestamp;
+ u32 length;
+ u32 dropped;
/* max ATH6KL_FWLOG_PAYLOAD_SIZE bytes */
u_int8_t payload[0];
-}__packed;
+}__attribute__((packed)) dbglog_slot;
typedef enum eAniNlModuleTypes {
ANI_NL_MSG_NETSIM = ANI_NL_MSG_BASE,// NetSim Messages (to the server)
@@ -112,6 +148,21 @@
u16 length;
} host_event_hdr_t;
+typedef struct fw_event_hdr_s
+{
+ u16 diag_type;
+ u16 length;
+} fw_event_hdr_t;
+
+typedef struct
+{
+ u32 timestamp:24;
+ u32 diag_event_type:8;
+ u16 payload_len;
+ u16 diag_id;
+ u8 payload[0];
+}__attribute__((packed)) fw_diag_msg_hdr_t;
+
typedef struct wlan_wake_lock_event {
u32 status;
u32 reason;
@@ -120,5 +171,43 @@
char name[];
} wlan_wake_lock_event_t;
-int diag_message_handler(hal_info *info, nl_msg *msg);
+enum log_event_type {
+ WLAN_LOG_TYPE_NON_FATAL,
+ WLAN_LOG_TYPE_FATAL,
+};
+
+enum log_event_indicator {
+ WLAN_LOG_INDICATOR_UNUSED,
+ WLAN_LOG_INDICATOR_FRAMEWORK,
+ WLAN_LOG_INDICATOR_HOST_DRIVER,
+ WLAN_LOG_INDICATOR_FIRMWARE,
+};
+
+enum log_event_host_reason_code {
+ WLAN_LOG_REASON_CODE_UNUSED,
+ WLAN_LOG_REASON_COMMAND_UNSUCCESSFUL,
+ WLAN_LOG_REASON_ROAM_FAIL,
+ WLAN_LOG_REASON_THREAD_STUCK,
+ WLAN_LOG_REASON_DATA_STALL,
+ WLAN_LOG_REASON_SME_COMMAND_STUCK,
+ WLAN_LOG_REASON_ZERO_SCAN_RESULTS,
+ WLAN_LOG_REASON_QUEUE_FULL,
+ WLAN_LOG_REASON_POWER_COLLAPSE_FAIL,
+ WLAN_LOG_REASON_SSR_FAIL,
+ WLAN_LOG_REASON_DISCONNECT_FAIL,
+ WLAN_LOG_REASON_CLEAN_UP_FAIL,
+ WLAN_LOG_REASON_MALLOC_FAIL,
+ WLAN_LOG_REASON_VOS_MSG_UNDER_RUN,
+ WLAN_LOG_REASON_MSG_POST_FAIL,
+};
+
+typedef struct {
+ u32 is_fatal;
+ u32 indicator;
+ u32 reason_code;
+ u32 reserved;
+} wlan_log_complete_event_t;
+
+wifi_error diag_message_handler(hal_info *info, nl_msg *msg);
+
#endif /* __WIFI_HAL_WIFILOGGER_DIAG_H__ */
diff --git a/qcwcn/wifi_hal/wifilogger_event_defs.h b/qcwcn/wifi_hal/wifilogger_event_defs.h
new file mode 100644
index 0000000..5b386c8
--- /dev/null
+++ b/qcwcn/wifi_hal/wifilogger_event_defs.h
@@ -0,0 +1,450 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WIFILOGGER_EVENT_DEFS_H
+#define WIFILOGGER_EVENT_DEFS_H
+
+typedef enum {
+ EVENT_DROP_ID = 0,
+
+ EVENT_WLAN_PE = 0x67A, /* 16 byte payload */
+
+ /* Events between 0x67b to 0x67f are not used */
+
+ EVENT_WLAN_ADD_BLOCK_ACK_SUCCESS = 0x67B, /* 11 byte payload */
+ EVENT_WLAN_ADD_BLOCK_ACK_FAILED = 0x67C, /* 9 byte payload */
+
+ EVENT_WLAN_EXTSCAN_FEATURE_STARTED = 0xA8E, /* 240 byte payload */
+ EVENT_WLAN_EXTSCAN_FEATURE_CHANNEL_CONFIG = 0xA8F, /* 243 byte payload */
+ EVENT_WLAN_EXTSCAN_CYCLE_STARTED = 0xA90, /* 12 byte payload */
+ EVENT_WLAN_EXTSCAN_CYCLE_COMPLETED = 0xA91, /* 12 byte payload */
+ EVENT_WLAN_EXTSCAN_BUCKET_STARTED = 0xA92, /* 1 byte payload */
+ EVENT_WLAN_EXTSCAN_BUCKET_COMPLETED = 0xA93, /* 4 byte payload */
+ EVENT_WLAN_ROAM_SCAN_STARTED = 0xA94, /* 128 byte payload */
+
+
+ EVENT_WLAN_ROAM_SCAN_COMPLETE = 0xA95,
+ EVENT_WLAN_ROAM_CANDIDATE_FOUND = 0xA96,
+ EVENT_WLAN_ROAM_SCAN_CONFIG = 0xA97,
+ EVENT_WLAN_BT_COEX_BT_SCO_START = 0xA98,
+ EVENT_WLAN_BT_COEX_BT_SCO_STOP = 0xA99,
+ EVENT_WLAN_BT_COEX_BT_SCAN_START = 0xA9A,
+ EVENT_WLAN_BT_COEX_BT_SCAN_STOP = 0xA9B,
+ EVENT_WIFI_BT_COEX_BT_HID_START = 0xA9C,
+ EVENT_WIFI_BT_COEX_BT_HID_STOP = 0xA9D,
+ EVENT_WLAN_WAKE_LOCK = 0xAA2, /* 96 bytes payload */
+ EVENT_WLAN_EAPOL = 0xA8D, /* 96 bytes payload */
+ EVENT_WLAN_EXTSCAN_FEATURE_STOP = 0xAA3,
+ EVENT_WLAN_EXTSCAN_RESULTS_AVAILABLE = 0xAA4,
+ EVENT_WLAN_LOG_COMPLETE = 0xAA7,
+
+ EVENT_MAX_ID = 0x0FFF
+} event_id_enum_type;
+
+typedef enum {
+ LOG_DROP_ID = 0,
+ LOG_WLAN_EXTSCAN_CAPABILITIES = 0x18F1,
+ LOG_WLAN_EXTSCAN_FEATURE_STARTED = 0x18F2,
+} log_id_enum_type;
+
+typedef enum
+{
+ WLAN_PE_DIAG_SCAN_REQ_EVENT = 0,
+ WLAN_PE_DIAG_SCAN_ABORT_IND_EVENT,
+ WLAN_PE_DIAG_SCAN_RSP_EVENT,
+ WLAN_PE_DIAG_JOIN_REQ_EVENT,
+ WLAN_PE_DIAG_JOIN_RSP_EVENT,
+ WLAN_PE_DIAG_SETCONTEXT_REQ_EVENT,
+ WLAN_PE_DIAG_SETCONTEXT_RSP_EVENT,
+ WLAN_PE_DIAG_REASSOC_REQ_EVENT,
+ WLAN_PE_DIAG_REASSOC_RSP_EVENT,
+ WLAN_PE_DIAG_AUTH_REQ_EVENT,
+ WLAN_PE_DIAG_AUTH_RSP_EVENT = 10,
+ WLAN_PE_DIAG_DISASSOC_REQ_EVENT,
+ WLAN_PE_DIAG_DISASSOC_RSP_EVENT,
+ WLAN_PE_DIAG_DISASSOC_IND_EVENT,
+ WLAN_PE_DIAG_DISASSOC_CNF_EVENT,
+ WLAN_PE_DIAG_DEAUTH_REQ_EVENT,
+ WLAN_PE_DIAG_DEAUTH_RSP_EVENT,
+ WLAN_PE_DIAG_DEAUTH_IND_EVENT,
+ WLAN_PE_DIAG_START_BSS_REQ_EVENT,
+ WLAN_PE_DIAG_START_BSS_RSP_EVENT,
+ WLAN_PE_DIAG_AUTH_IND_EVENT = 20,
+ WLAN_PE_DIAG_ASSOC_IND_EVENT,
+ WLAN_PE_DIAG_ASSOC_CNF_EVENT,
+ WLAN_PE_DIAG_REASSOC_IND_EVENT,
+ WLAN_PE_DIAG_SWITCH_CHL_REQ_EVENT,
+ WLAN_PE_DIAG_SWITCH_CHL_RSP_EVENT,
+ WLAN_PE_DIAG_STOP_BSS_REQ_EVENT,
+ WLAN_PE_DIAG_STOP_BSS_RSP_EVENT,
+ WLAN_PE_DIAG_DEAUTH_CNF_EVENT,
+ WLAN_PE_DIAG_ADDTS_REQ_EVENT,
+ WLAN_PE_DIAG_ADDTS_RSP_EVENT = 30,
+ WLAN_PE_DIAG_DELTS_REQ_EVENT,
+ WLAN_PE_DIAG_DELTS_RSP_EVENT,
+ WLAN_PE_DIAG_DELTS_IND_EVENT,
+ WLAN_PE_DIAG_ENTER_BMPS_REQ_EVENT,
+ WLAN_PE_DIAG_ENTER_BMPS_RSP_EVENT,
+ WLAN_PE_DIAG_EXIT_BMPS_REQ_EVENT,
+ WLAN_PE_DIAG_EXIT_BMPS_RSP_EVENT,
+ WLAN_PE_DIAG_EXIT_BMPS_IND_EVENT,
+ WLAN_PE_DIAG_ENTER_IMPS_REQ_EVENT,
+ WLAN_PE_DIAG_ENTER_IMPS_RSP_EVENT = 40,
+ WLAN_PE_DIAG_EXIT_IMPS_REQ_EVENT,
+ WLAN_PE_DIAG_EXIT_IMPS_RSP_EVENT,
+ WLAN_PE_DIAG_ENTER_UAPSD_REQ_EVENT,
+ WLAN_PE_DIAG_ENTER_UAPSD_RSP_EVENT,
+ WLAN_PE_DIAG_EXIT_UAPSD_REQ_EVENT,
+ WLAN_PE_DIAG_EXIT_UAPSD_RSP_EVENT,
+ WLAN_PE_DIAG_WOWL_ADD_BCAST_PTRN_EVENT,
+ WLAN_PE_DIAG_WOWL_DEL_BCAST_PTRN_EVENT,
+ WLAN_PE_DIAG_ENTER_WOWL_REQ_EVENT,
+ WLAN_PE_DIAG_ENTER_WOWL_RSP_EVENT = 50,
+ WLAN_PE_DIAG_EXIT_WOWL_REQ_EVENT,
+ WLAN_PE_DIAG_EXIT_WOWL_RSP_EVENT,
+ WLAN_PE_DIAG_HAL_ADDBA_REQ_EVENT,
+ WLAN_PE_DIAG_HAL_ADDBA_RSP_EVENT,
+ WLAN_PE_DIAG_HAL_DELBA_IND_EVENT,
+ WLAN_PE_DIAG_HB_FAILURE_TIMEOUT,
+ WLAN_PE_DIAG_PRE_AUTH_REQ_EVENT,
+ WLAN_PE_DIAG_PRE_AUTH_RSP_EVENT,
+ WLAN_PE_DIAG_PREAUTH_DONE,
+ WLAN_PE_DIAG_REASSOCIATING = 60,
+ WLAN_PE_DIAG_CONNECTED,
+ WLAN_PE_DIAG_ASSOC_REQ_EVENT,
+ WLAN_PE_DIAG_AUTH_COMP_EVENT,
+ WLAN_PE_DIAG_ASSOC_COMP_EVENT,
+ WLAN_PE_DIAG_AUTH_START_EVENT,
+ WLAN_PE_DIAG_ASSOC_START_EVENT,
+ WLAN_PE_DIAG_REASSOC_START_EVENT,
+ WLAN_PE_DIAG_ROAM_AUTH_START_EVENT,
+ WLAN_PE_DIAG_ROAM_AUTH_COMP_EVENT,
+ WLAN_PE_DIAG_ROAM_ASSOC_START_EVENT = 70,
+ WLAN_PE_DIAG_ROAM_ASSOC_COMP_EVENT,
+ WLAN_PE_DIAG_SCAN_COMP_EVENT,
+ WLAN_PE_DIAG_SCAN_RES_FOUND_EVENT,
+} wlan_host_diag_event_type;
+
+typedef struct wlan_pe_event {
+ char bssid[6];
+ u16 event_type;
+ u16 sme_state;
+ u16 mlm_state;
+ u16 status;
+ u16 reason_code;
+} __attribute__((packed)) wlan_pe_event_t;
+
+typedef enum {
+ WLAN_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED = 0,
+ WLAN_DRIVER_EAPOL_FRAME_RECEIVED,
+} wlan_eapol_event_type;
+
+#define EAPOL_MASK 0x8013
+#define EAPOL_M1_MASK 0x8000
+#define EAPOL_M2_MASK 0x0001
+#define EAPOL_M3_MASK 0x8013
+#define EAPOL_M4_MASK 0x0003
+
+typedef struct wlan_eapol_event {
+ u8 event_sub_type;
+ u8 eapol_packet_type;
+ u16 eapol_key_info;
+ u16 eapol_rate;
+ u8 dest_addr[6];
+ u8 src_addr[6];
+} __attribute__((packed)) wlan_eapol_event_t;
+
+/*EVENT_WLAN_EXTSCAN_FEATURE_STARTED */
+typedef struct wlan_ext_bucket {
+ u8 bucket_id;
+ u8 base_period_multiplier;
+ u16 min_dwell_time_active;
+ u16 max_dwell_time_active;
+ u16 min_dwell_time_passive;
+ u16 max_dwell_time_passive;
+ u8 num_channels;
+ u8 channel_offset;
+ u8 forwarding_flags;
+ u8 channel_band;
+ u32 notify_extscan_events;
+} __attribute__((packed)) wlan_ext_bucket_t;
+
+typedef struct {
+ u32 base_period;
+ u32 max_iterations;
+ u32 forwarding_flags;
+ u32 configuration_flags;
+ u32 notify_extscan_events;
+ u32 scan_priority;
+ u32 max_bssids_per_scan_cycle;
+ u32 min_rssi;
+ u32 max_table_usage;
+ u32 min_dwell_time_active;
+ u32 max_dwell_time_active;
+ u32 min_dwell_time_passive;
+ u32 max_dwell_time_passive;
+ u32 min_rest_time;
+ u32 max_rest_time;
+ u32 n_probes;
+ u32 repeat_probe_time;
+ u32 probe_spacing_time;
+ u32 idle_time;
+ u32 max_scan_time;
+ u32 probe_delay;
+ u32 scan_ctrl_flags;
+ u32 burst_duration;
+ u32 num_buckets;
+ wlan_ext_bucket bucket_list[8];
+} __attribute__((packed)) wlan_ext_scan_feature_started_payload_type;
+/*End EVENT_WLAN_EXTSCAN_FEATURE_STARTED*/
+
+/*EVENT_WLAN_EXTSCAN_FEATURE_CHANNEL_CONFIG*/
+typedef struct {
+ u8 bucket_id;
+ u16 scan_channels[40];
+} __attribute__((packed)) wlan_ext_bucket_channels;
+
+typedef struct {
+ wlan_ext_bucket_channels bucket_list[3];
+} __attribute__((packed)) wlan_ext_bucket_channel_config_payload_type;
+
+/*End EVENT_WLAN_EXTSCAN_FEATURE_CHANNEL_CONFIG*/
+
+/*EVENT_WLAN_EXTSCAN_CYCLE_STARTED*/
+typedef struct {
+ u32 scan_id;
+ u32 timer_tick;
+ u32 scheduled_bucket_mask;
+ u32 scan_cycle_count;
+} __attribute__((packed)) wlan_ext_scan_cycle_started_payload_type;
+/*End EVENT_WLAN_EXTSCAN_CYCLE_STARTED*/
+
+/*EVENT_WLAN_EXTSCAN_CYCLE_COMPLETED*/
+typedef struct {
+ u32 scan_id;
+ u32 timer_tick;
+ u32 scheduled_bucket_mask;
+ u32 scan_cycle_count;
+} __attribute__((packed)) wlan_ext_scan_cycle_completed_payload_type;
+/*End EVENT_WLAN_EXTSCAN_CYCLE_COMPLETED*/
+
+/*EVENT_WLAN_EXTSCAN_BUCKET_STARTED*/
+typedef struct {
+ u8 bucket_id;
+} __attribute__((packed)) wlan_ext_scan_bucket_started_payload_type;
+/*End EVENT_WLAN_EXTSCAN_BUCKET_STARTED*/
+
+/*EVENT_WLAN_EXTSCAN_BUCKET_COMPLETED*/
+typedef struct {
+ u8 bucket_id;
+} __attribute__((packed)) wlan_ext_scan_bucket_completed_payload_type;
+/*End EVENT_WLAN_EXTSCAN_BUCKET_COMPLETED*/
+
+/*EVENT_WLAN_ROAM_SCAN_STARTED*/
+typedef struct {
+ u32 scan_id;
+ u32 roam_scan_flags;
+ u32 cur_rssi;
+ u16 scan_params[18];
+ u16 scan_channels[40]; // first 40 channels only
+} __attribute__((packed)) wlan_roam_scan_started_payload_type;
+/*End EVENT_WLAN_ROAM_SCAN_STARTED*/
+
+/*EVENT_WLAN_ROAM_SCAN_COMPLETE*/
+typedef struct {
+ u32 scan_id;
+ u32 reason;
+ u32 completion_flags;
+ u32 num_candidate;
+ u32 flags;
+} __attribute__((packed)) wlan_roam_scan_complete_payload_type;
+/*End EVENT_WLAN_ROAM_SCAN_COMPLETE*/
+
+/*EVENT_WLAN_ROAM_CANDIDATE_FOUND*/
+typedef struct {
+ u8 channel;
+ u8 rssi;
+ u8 bssid[6];
+ u8 ssid[33];
+ u8 auth_mode;
+ u8 ucast_cipher;
+ u8 mcast_cipher;
+} __attribute__((packed)) wlan_roam_candidate_found_payload_type;
+/*End EVENT_WLAN_ROAM_CANDIDATE_FOUND*/
+
+/*EVENT_WLAN_ROAM_SCAN_CONFIG*/
+typedef struct {
+ u32 flags;
+ u32 roam_scan_config[8];
+} __attribute__((packed)) wlan_roam_scan_config_payload_type;
+/*End EVENT_WLAN_ROAM_SCAN_CONFIG*/
+
+/* EVENT_WLAN_BT_COEX_BT_SCO_START */
+typedef struct {
+ u8 link_id;
+ u8 link_state;
+ u8 link_role;
+ u8 link_type;
+ u16 Tsco;
+ u8 Rsco;
+} __attribute__((packed)) wlan_bt_coex_bt_sco_start_payload_type;
+/* End EVENT_WLAN_BT_COEX_BT_SCO_START */
+
+/* EVENT_WLAN_BT_COEX_BT_SCO_STOP */
+typedef struct {
+ u8 link_id;
+ u8 link_state;
+ u8 link_role;
+ u8 link_type;
+ u16 Tsco;
+ u8 Rsco;
+} __attribute__((packed)) wlan_bt_coex_bt_sco_stop_payload_type;
+/*End EVENT_WLAN_BT_COEX_BT_SCO_STOP*/
+
+/* EVENT_WLAN_BT_COEX_BT_SCAN_START */
+typedef struct {
+ u8 scan_type;
+ u8 scan_bitmap;
+} __attribute__((packed)) wlan_bt_coex_bt_scan_start_payload_type;
+
+/*End EVENT_WLAN_BT_COEX_BT_SCAN_START*/
+
+/* EVENT_WLAN_BT_COEX_BT_SCAN_STOP */
+typedef struct {
+ u8 scan_type;
+ u8 scan_bitmap;
+} __attribute__((packed)) wlan_bt_coex_bt_scan_stop_payload_type;
+/*End EVENT_WLAN_BT_COEX_BT_SCAN_STOP*/
+
+/*EVENT_WIFI_BT_COEX_BT_HID_START */
+typedef struct {
+ u8 link_id;
+ u8 link_state;
+ u8 link_role;
+ u8 Tsniff;
+ u8 attempts;
+} __attribute__((packed)) wlan_bt_coex_bt_hid_start_payload_type;
+/*End EVENT_WIFI_BT_COEX_BT_HID_START */
+
+/* EVENT_WIFI_BT_COEX_BT_HID_STOP */
+typedef struct {
+ u8 link_id;
+ u8 link_state;
+ u8 link_role;
+ u8 Tsniff;
+ u8 attempts;
+} __attribute__((packed)) wlan_bt_coex_bt_hid_stop_payload_type;
+/* End EVENT_WIFI_BT_COEX_BT_HID_STOP */
+
+/* EVENT_WLAN_EXTSCAN_FEATURE_STOP */
+typedef struct {
+ u32 request_id;
+} __attribute__((packed)) wlan_ext_scan_feature_stop_payload_type;
+/* End EVENT_WLAN_EXTSCAN_FEATURE_STOP */
+
+/* EVENT_WLAN_EXTSCAN_RESULTS_AVAILABLE */
+typedef struct {
+ u32 request_id;
+ u32 table_type;
+ u32 entries_in_use;
+ u32 maximum_entries;
+ u32 scan_count_after_getResults;
+ u8 threshold_num_scans;
+} __attribute__((packed)) wlan_ext_scan_results_available_payload_type;
+/* End EVENT_WLAN_EXTSCAN_RESULTS_AVAILABLE */
+
+/* EVENT_WLAN_EXTSCAN_CAPABILITIES */
+typedef struct {
+ u32 header;
+ u32 request_id;
+ u32 requestor_id;
+ u32 vdev_id;
+ u32 num_extscan_cache_tables;
+ u32 num_wlan_change_monitor_tables;
+ u32 num_hotlist_monitor_tables;
+ u32 rtt_one_sided_supported;
+ u32 rtt_11v_supported;
+ u32 rtt_ftm_supported;
+ u32 num_extscan_cache_capabilities;
+ u32 num_extscan_wlan_change_capabilities;
+ u32 num_extscan_hotlist_capabilities;
+ u32 num_roam_ssid_whitelist;
+ u32 num_roam_bssid_blacklist;
+ u32 num_roam_bssid_preferred_list;
+ u32 num_extscan_hotlist_ssid;
+ u32 num_epno_networks;
+} __attribute__((packed)) wlan_extscan_capabilities_event_fixed_param;
+
+typedef struct {
+ u32 header;
+ u32 table_id;
+ u32 scan_cache_entry_size;
+ u32 max_scan_cache_entries;
+ u32 max_buckets;
+ u32 max_bssid_per_scan;
+ u32 max_table_usage_threshold;
+} __attribute__((packed)) wlan_extscan_cache_capabilities;
+
+typedef struct {
+ u32 tlv_header;
+ u32 table_id;
+ u32 wlan_hotlist_entry_size;
+ u32 max_hotlist_entries;
+} __attribute__((packed)) wlan_extscan_hotlist_monitor_capabilities;
+
+typedef struct {
+ u32 request_id;
+ wlan_extscan_capabilities_event_fixed_param extscan_capabilities;
+ wlan_extscan_cache_capabilities extscan_cache_capabilities;
+ wlan_extscan_hotlist_monitor_capabilities extscan_hotlist_monitor_capabilities;
+} __attribute__((packed)) wlan_ext_scan_capabilities_payload_type;
+/* End EVENT_WLAN_EXTSCAN_CAPABILITIES*/
+
+/* EVENT_WLAN_BEACON_RECEIVED */
+typedef struct {
+ u32 beacon_rssi;
+} __attribute__((packed)) wlan_beacon_received_payload_type;
+/* End EVENT_WLAN_BEACON_RECEIVED */
+
+typedef struct {
+ u8 ucBaPeerMac[6];
+ u8 ucBaTid;
+ u8 ucBaBufferSize;
+ u16 ucBaSSN;
+ u8 fInitiator;
+} __attribute__((packed)) wlan_add_block_ack_success_payload_type;
+
+/* EVENT_WLAN_ADD_BLOCK_ACK_FAILED */
+typedef struct {
+ u8 ucBaPeerMac[6];
+ u8 ucBaTid;
+ u8 ucReasonCode;
+ u8 fInitiator;
+} __attribute__((packed)) wlan_add_block_ack_failed_payload_type;
+
+#endif /* WIFILOGGER_EVENT_DEFS_H */
diff --git a/qcwcn/wifi_hal/wifilogger_vendor_tag_defs.h b/qcwcn/wifi_hal/wifilogger_vendor_tag_defs.h
new file mode 100644
index 0000000..8b8aadf
--- /dev/null
+++ b/qcwcn/wifi_hal/wifilogger_vendor_tag_defs.h
@@ -0,0 +1,111 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __WIFI_HAL_WIFILOGGER_VENDOR_EVENTS_H__
+#define __WIFI_HAL_WIFILOGGER_VENDOR_EVENTS_H__
+
+#include "common.h"
+
+typedef struct {
+ u8 Tsniff;
+ u8 attempts;
+} bt_coex_hid_vendor_data_t;
+
+typedef struct {
+ u32 timer_tick;
+ u32 scheduled_bucket_mask;
+ u32 scan_cycle_count;
+} __attribute__((packed)) ext_scan_cycle_vendor_data_t;
+
+typedef struct {
+ u32 table_type;
+ u32 entries_in_use;
+ u32 maximum_entries;
+ u32 scan_count_after_getResults;
+ u8 threshold_num_scans;
+} __attribute__((packed)) ext_scan_results_available_vendor_data_t;
+
+typedef struct {
+ u32 roam_scan_flags;
+ u32 cur_rssi;
+ u16 scan_params[18];
+ u16 scan_channels[40]; // first 40 channels only
+} __attribute__((packed)) roam_scan_started_vendor_data_t;
+
+typedef struct {
+ u32 reason;
+ u32 completion_flags;
+ u32 num_candidate;
+ u32 flags;
+} __attribute__((packed)) roam_scan_complete_vendor_data_t;
+
+typedef struct {
+ u8 ssid[33];
+ u8 auth_mode;
+ u8 ucast_cipher;
+ u8 mcast_cipher;
+} __attribute__((packed)) roam_candidate_found_vendor_data_t;
+
+typedef struct {
+ u32 flags;
+ u32 roam_scan_config[8];
+} __attribute__((packed)) roam_scan_config_vendor_data_t;
+
+typedef struct {
+ u8 scan_type;
+ u8 scan_bitmap;
+} __attribute__((packed)) bt_coex_bt_scan_start_vendor_data_t;
+
+typedef struct {
+ u8 scan_type;
+ u8 scan_bitmap;
+} __attribute__((packed)) bt_coex_bt_scan_stop_vendor_data_t;
+
+typedef struct {
+ u16 sme_state;
+ u16 mlm_state;
+} __attribute__((packed)) pe_event_vendor_data_t;
+
+typedef enum {
+ ADDBA_SUCCESS = 0,
+ ADDBA_FAILURE = -1,
+} addba_status_t;
+
+typedef struct {
+ u8 ucBaTid;
+ u8 ucBaBufferSize;
+ u16 ucBaSSN;
+ u8 fInitiator;
+} __attribute__((packed)) addba_success_vendor_data_t;
+
+typedef struct {
+ u8 ucBaTid;
+ u8 fInitiator;
+} __attribute__((packed)) addba_failed_vendor_data_t;
+
+#endif /* __WIFI_HAL_WIFILOGGER_VENDOR_EVENTS_H__ */
diff --git a/qcwcn/wifi_hal/wifiloggercmd.h b/qcwcn/wifi_hal/wifiloggercmd.h
index 3b63ed4..a03b8df 100644
--- a/qcwcn/wifi_hal/wifiloggercmd.h
+++ b/qcwcn/wifi_hal/wifiloggercmd.h
@@ -67,8 +67,8 @@
{
private:
WifiLoggerCallbackHandler mHandler;
- char **mVersion;
- int *mVersionLen;
+ char *mVersion;
+ int mVersionLen;
u32 *mSupportedSet;
int mRequestId;
bool mWaitforRsp;
@@ -93,12 +93,14 @@
/* Takes wait time in seconds. */
virtual int timed_wait(u16 wait_time);
virtual void waitForRsp(bool wait);
- virtual void setVersionInfo(char **buffer, int *buffer_size);
+ virtual void setVersionInfo(char *buffer, int buffer_size);
virtual void setFeatureSet(u32 *support);
};
void rb_timerhandler(hal_info *info);
wifi_error wifi_logger_ring_buffers_init(hal_info *info);
void wifi_logger_ring_buffers_deinit(hal_info *info);
+void push_out_all_ring_buffers(hal_info *info);
+void send_alert(hal_info *info, int reason_code);
#ifdef __cplusplus
}
#endif /* __cplusplus */