diff --git a/utils/epping/inc/epping_internal.h b/utils/epping/inc/epping_internal.h new file mode 100644 index 0000000000..d2b7bcf54d --- /dev/null +++ b/utils/epping/inc/epping_internal.h @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef EPPING_INTERNAL_H +#define EPPING_INTERNAL_H +/**=========================================================================== + + \file epping_internal.h + + \brief Linux epping internal head file + + ==========================================================================*/ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#if defined(WLAN_OPEN_SOURCE) && defined(CONFIG_HAS_WAKELOCK) +#include +#endif +#include "htc_api.h" +#include "htc_packet.h" +#include "epping_test.h" +#include +#include +#include + +#define EPPING_LOG_MASK (1< +#include + +/* epping_main signatures */ +int epping_open(void); +void epping_close(void); +void epping_disable(void); +int epping_enable(struct device *parent_dev); +#endif /* end #ifndef EPPING_MAIN_H */ diff --git a/utils/epping/src/epping_helper.c b/utils/epping/src/epping_helper.c new file mode 100644 index 0000000000..65cefaea40 --- /dev/null +++ b/utils/epping/src/epping_helper.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*======================================================================== + + \file epping_main.c + + \brief WLAN End Point Ping test tool implementation + + ========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "epping_main.h" +#include "epping_internal.h" + +int epping_cookie_init(epping_context_t *pEpping_ctx) +{ + A_UINT32 i, j; + + pEpping_ctx->cookie_list = NULL; + pEpping_ctx->cookie_count = 0; + for (i = 0; i < MAX_COOKIE_SLOTS_NUM; i++) { + pEpping_ctx->s_cookie_mem[i] = + qdf_mem_malloc(sizeof(struct epping_cookie) * + MAX_COOKIE_SLOT_SIZE); + if (pEpping_ctx->s_cookie_mem[i] == NULL) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: no mem for cookie (idx = %d)", __func__, + i); + goto error; + } + } + qdf_spinlock_create(&pEpping_ctx->cookie_lock); + + for (i = 0; i < MAX_COOKIE_SLOTS_NUM; i++) { + struct epping_cookie *cookie_mem = pEpping_ctx->s_cookie_mem[i]; + for (j = 0; j < MAX_COOKIE_SLOT_SIZE; j++) { + epping_free_cookie(pEpping_ctx, &cookie_mem[j]); + } + } + return 0; +error: + for (i = 0; i < MAX_COOKIE_SLOTS_NUM; i++) { + if (pEpping_ctx->s_cookie_mem[i]) { + qdf_mem_free(pEpping_ctx->s_cookie_mem[i]); + pEpping_ctx->s_cookie_mem[i] = NULL; + } + } + return -ENOMEM; +} + +/* cleanup cookie queue */ +void epping_cookie_cleanup(epping_context_t *pEpping_ctx) +{ + int i; + qdf_spin_lock_bh(&pEpping_ctx->cookie_lock); + pEpping_ctx->cookie_list = NULL; + pEpping_ctx->cookie_count = 0; + qdf_spin_unlock_bh(&pEpping_ctx->cookie_lock); + for (i = 0; i < MAX_COOKIE_SLOTS_NUM; i++) { + if (pEpping_ctx->s_cookie_mem[i]) { + qdf_mem_free(pEpping_ctx->s_cookie_mem[i]); + pEpping_ctx->s_cookie_mem[i] = NULL; + } + } +} + +void epping_free_cookie(epping_context_t *pEpping_ctx, + struct epping_cookie *cookie) +{ + qdf_spin_lock_bh(&pEpping_ctx->cookie_lock); + cookie->next = pEpping_ctx->cookie_list; + pEpping_ctx->cookie_list = cookie; + pEpping_ctx->cookie_count++; + qdf_spin_unlock_bh(&pEpping_ctx->cookie_lock); +} + +struct epping_cookie *epping_alloc_cookie(epping_context_t *pEpping_ctx) +{ + struct epping_cookie *cookie; + + qdf_spin_lock_bh(&pEpping_ctx->cookie_lock); + cookie = pEpping_ctx->cookie_list; + if (cookie != NULL) { + pEpping_ctx->cookie_list = cookie->next; + pEpping_ctx->cookie_count--; + } + qdf_spin_unlock_bh(&pEpping_ctx->cookie_lock); + return cookie; +} + +void epping_get_dummy_mac_addr(tSirMacAddr macAddr) +{ + macAddr[0] = 69; /* E */ + macAddr[1] = 80; /* P */ + macAddr[2] = 80; /* P */ + macAddr[3] = 73; /* I */ + macAddr[4] = 78; /* N */ + macAddr[5] = 71; /* G */ +} + +void epping_hex_dump(void *data, int buf_len, const char *str) +{ + char *buf = (char *)data; + int i; + + printk("%s: E, %s\n", __func__, str); + for (i = 0; (i + 7) < buf_len; i += 8) { + printk("%02x %02x %02x %02x %02x %02x %02x %02x\n", + buf[i], + buf[i + 1], + buf[i + 2], + buf[i + 3], + buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7]); + } + + /* Dump the bytes in the last line */ + for (; i < buf_len; i++) { + printk("%02x ", buf[i]); + } + printk("\n%s: X %s\n", __func__, str); +} + +void *epping_get_qdf_ctx(void) +{ + qdf_device_t *qdf_ctx; + + qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); + return qdf_ctx; +} + +void epping_log_packet(epping_adapter_t *pAdapter, + EPPING_HEADER *eppingHdr, int ret, const char *str) +{ + if (eppingHdr->Cmd_h & EPPING_LOG_MASK) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: cmd = %d, seqNo = %u, flag = 0x%x, ret = %d, " + "txCount = %lu, txDrop = %lu, txBytes = %lu," + "rxCount = %lu, rxDrop = %lu, rxBytes = %lu\n", + str, eppingHdr->Cmd_h, eppingHdr->SeqNo, + eppingHdr->CmdFlags_h, ret, + pAdapter->stats.tx_packets, + pAdapter->stats.tx_dropped, + pAdapter->stats.tx_bytes, + pAdapter->stats.rx_packets, + pAdapter->stats.rx_dropped, + pAdapter->stats.rx_bytes); + } +} + +void epping_log_stats(epping_adapter_t *pAdapter, const char *str) +{ + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: txCount = %lu, txDrop = %lu, tx_bytes = %lu, " + "rxCount = %lu, rxDrop = %lu, rx_bytes = %lu, tx_acks = %u\n", + str, + pAdapter->stats.tx_packets, + pAdapter->stats.tx_dropped, + pAdapter->stats.tx_bytes, + pAdapter->stats.rx_packets, + pAdapter->stats.rx_dropped, + pAdapter->stats.rx_bytes, + pAdapter->pEpping_ctx->total_tx_acks); +} + +void epping_set_kperf_flag(epping_adapter_t *pAdapter, + HTC_ENDPOINT_ID eid, A_UINT8 kperf_flag) +{ + pAdapter->pEpping_ctx->kperf_num_rx_recv[eid] = 0; + pAdapter->pEpping_ctx->kperf_num_tx_acks[eid] = 0; +} diff --git a/utils/epping/src/epping_main.c b/utils/epping/src/epping_main.c new file mode 100644 index 0000000000..3e47798b18 --- /dev/null +++ b/utils/epping/src/epping_main.c @@ -0,0 +1,354 @@ +/* + * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*======================================================================== + + \file epping_main.c + + \brief WLAN End Point Ping test tool implementation + + ========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "bmi.h" +#include "ol_fw.h" +#include "ol_if_athvar.h" +#include "hif.h" +#include "epping_main.h" +#include "epping_internal.h" +#include "cds_concurrency.h" + +#ifdef TIMER_MANAGER +#define TIMER_MANAGER_STR " +TIMER_MANAGER" +#else +#define TIMER_MANAGER_STR "" +#endif + +#ifdef MEMORY_DEBUG +#define MEMORY_DEBUG_STR " +MEMORY_DEBUG" +#else +#define MEMORY_DEBUG_STR "" +#endif + +#ifdef HIF_SDIO +#define WLAN_WAIT_TIME_WLANSTART 10000 +#else +#define WLAN_WAIT_TIME_WLANSTART 2000 +#endif + +static struct epping_context *g_epping_ctx; + +/** + * epping_open(): End point ping driver open Function + * + * This function is called by HDD to open epping module + * + * + * return - 0 for success, negative for failure + */ +int epping_open(void) +{ + EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: Enter", __func__); + + g_epping_ctx = qdf_mem_malloc(sizeof(*g_epping_ctx)); + + if (g_epping_ctx == NULL) { + EPPING_LOG(QDF_TRACE_LEVEL_ERROR, + "%s: cannot alloc epping context", __func__); + return -ENOMEM; + } + + g_epping_ctx->con_mode = cds_get_conparam(); + return 0; +} + +/** + * epping_disable(): End point ping driver disable Function + * + * This is the driver disable function - called by HDD to + * disable epping module + * + * return: none + */ +void epping_disable(void) +{ + epping_context_t *pEpping_ctx; + struct hif_opaque_softc *hif_ctx; + HTC_HANDLE htc_handle; + + pEpping_ctx = g_epping_ctx; + if (pEpping_ctx == NULL) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: error: pEpping_ctx = NULL", __func__); + return; + } + + if (pEpping_ctx->epping_adapter) { + epping_destroy_adapter(pEpping_ctx->epping_adapter); + pEpping_ctx->epping_adapter = NULL; + } + + hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); + if (hif_ctx == NULL) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: error: hif_ctx = NULL", __func__); + return; + } + hif_disable_isr(hif_ctx); + hif_reset_soc(hif_ctx); + + htc_handle = cds_get_context(QDF_MODULE_ID_HTC); + if (htc_handle == NULL) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: error: htc_handle = NULL", __func__); + return; + } + htc_stop(htc_handle); + epping_cookie_cleanup(pEpping_ctx); + htc_destroy(htc_handle); +} + +/** + * epping_close(): End point ping driver close Function + * + * This is the driver close function - called by HDD to close epping module + * + * return: none + */ +void epping_close(void) +{ + epping_context_t *to_free; + + + if (g_epping_ctx == NULL) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: error: g_epping_ctx = NULL", __func__); + return; + } + + to_free = g_epping_ctx; + g_epping_ctx = NULL; + qdf_mem_free(to_free); +} + +/** + * epping_target_suspend_acknowledge() - process wow ack/nack from fw + * @context: HTC_INIT_INFO->context + * @wow_nack: true when wow is rejected + */ +static void epping_target_suspend_acknowledge(void *context, bool wow_nack) +{ + if (NULL == g_epping_ctx) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: epping_ctx is NULL", __func__); + return; + } + /* EPPING_TODO: do we need wow_nack? */ + g_epping_ctx->wow_nack = wow_nack; +} + +/** + * epping_update_ol_config - API to update ol configuration parameters + * + * Return: void + */ +static void epping_update_ol_config(void) +{ + struct ol_config_info cfg; + struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI); + + if (!ol_ctx) + return; + + cfg.enable_self_recovery = 0; + cfg.enable_uart_print = 0; + cfg.enable_fw_log = 0; + cfg.enable_ramdump_collection = 0; + cfg.enable_lpass_support = 0; + + ol_init_ini_config(ol_ctx, &cfg); +} +/** + * epping_enable(): End point ping driver enable Function + * + * This is the driver enable function - called by HDD to enable + * epping module + * + * return - 0 : success, negative: error + */ +int epping_enable(struct device *parent_dev) +{ + int ret = 0; + epping_context_t *pEpping_ctx = NULL; + cds_context_type *p_cds_context = NULL; + qdf_device_t qdf_ctx; + HTC_INIT_INFO htcInfo; + struct hif_opaque_softc *scn; + tSirMacAddr adapter_macAddr; + struct hif_target_info *tgt_info; + struct ol_context *ol_ctx; + + EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: Enter", __func__); + + p_cds_context = cds_get_global_context(); + + if (p_cds_context == NULL) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: Failed cds_get_global_context", __func__); + ret = -1; + return ret; + } + + pEpping_ctx = g_epping_ctx; + if (pEpping_ctx == NULL) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: Failed to get pEpping_ctx", __func__); + ret = -1; + return ret; + } + pEpping_ctx->parent_dev = (void *)parent_dev; + epping_get_dummy_mac_addr(adapter_macAddr); + + /* Initialize the timer module */ + qdf_timer_module_init(); + + scn = cds_get_context(QDF_MODULE_ID_HIF); + if (!scn) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL, + "%s: scn is null!", __func__); + return A_ERROR; + } + + tgt_info = hif_get_target_info_handle(scn); + + /* store target type and target version info in hdd ctx */ + pEpping_ctx->target_type = tgt_info->target_type; + + ol_ctx = cds_get_context(QDF_MODULE_ID_BMI); + if (!ol_ctx) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL, + "%s: ol_ctx is NULL", __func__); + return A_ERROR; + } + + epping_update_ol_config(); +#ifndef FEATURE_BMI_2 + /* Initialize BMI and Download firmware */ + if (bmi_download_firmware(ol_ctx)) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL, + "%s: BMI failed to download target", __func__); + bmi_cleanup(ol_ctx); + return A_ERROR; + } +#endif + EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, + "%s: bmi_download_firmware done", __func__); + + htcInfo.pContext = ol_ctx; + htcInfo.TargetFailure = ol_target_failure; + htcInfo.TargetSendSuspendComplete = epping_target_suspend_acknowledge; + qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); + + /* Create HTC */ + p_cds_context->htc_ctx = htc_create(scn, &htcInfo, qdf_ctx, + cds_get_conparam()); + if (!p_cds_context->htc_ctx) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL, + "%s: Failed to Create HTC", __func__); + bmi_cleanup(ol_ctx); + return A_ERROR; + } + pEpping_ctx->HTCHandle = + cds_get_context(QDF_MODULE_ID_HTC); + if (pEpping_ctx->HTCHandle == NULL) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: HTCHandle is NULL", __func__); + return A_ERROR; + } + + if (bmi_done(ol_ctx)) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: Failed to complete BMI phase", __func__); + goto error_end; + } + + /* start HIF */ + if (htc_wait_target(pEpping_ctx->HTCHandle) != A_OK) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: htc_wait_target error", __func__); + goto error_end; + } + EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: HTC ready", __func__); + + ret = epping_connect_service(pEpping_ctx); + if (ret != 0) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: htc_wait_targetdone", __func__); + goto error_end; + } + if (htc_start(pEpping_ctx->HTCHandle) != A_OK) { + goto error_end; + } + EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: HTC started", __func__); + + /* init the tx cookie resource */ + ret = epping_cookie_init(pEpping_ctx); + if (ret == 0) { + pEpping_ctx->epping_adapter = epping_add_adapter(pEpping_ctx, + adapter_macAddr, + QDF_STA_MODE); + } + if (ret < 0 || pEpping_ctx->epping_adapter == NULL) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: epping_add_adaptererror error", __func__); + htc_stop(pEpping_ctx->HTCHandle); + epping_cookie_cleanup(pEpping_ctx); + goto error_end; + } + + EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: Exit", __func__); + return ret; + +error_end: + htc_destroy(p_cds_context->htc_ctx); + p_cds_context->htc_ctx = NULL; + bmi_cleanup(ol_ctx); + return A_ERROR; +} diff --git a/utils/epping/src/epping_rx.c b/utils/epping/src/epping_rx.c new file mode 100644 index 0000000000..85776c6f73 --- /dev/null +++ b/utils/epping/src/epping_rx.c @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*======================================================================== + + \file epping_rx.c + + \brief WLAN End Point Ping test tool implementation + + ========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "epping_main.h" +#include "epping_internal.h" +#include "epping_test.h" +#include + +#define AR6000_MAX_RX_BUFFERS 16 +#define AR6000_BUFFER_SIZE 1664 +#define AR6000_MIN_HEAD_ROOM 64 + +static bool enb_rx_dump; + +#ifdef HIF_SDIO +void epping_refill(void *ctx, HTC_ENDPOINT_ID Endpoint) +{ + epping_context_t *pEpping_ctx = (epping_context_t *) ctx; + void *osBuf; + int RxBuffers; + int buffersToRefill; + HTC_PACKET *pPacket; + HTC_PACKET_QUEUE queue; + + buffersToRefill = (int)AR6000_MAX_RX_BUFFERS - + htc_get_num_recv_buffers(pEpping_ctx->HTCHandle, Endpoint); + + if (buffersToRefill <= 0) { + /* fast return, nothing to fill */ + return; + } + + INIT_HTC_PACKET_QUEUE(&queue); + + EPPING_LOG(QDF_TRACE_LEVEL_INFO, + "%s: providing htc with %d buffers at eid=%d\n", + __func__, buffersToRefill, Endpoint); + + for (RxBuffers = 0; RxBuffers < buffersToRefill; RxBuffers++) { + osBuf = qdf_nbuf_alloc(NULL, AR6000_BUFFER_SIZE, + AR6000_MIN_HEAD_ROOM, 4, false); + if (NULL == osBuf) { + break; + } + /* the HTC packet wrapper is at the head of the reserved area + * in the skb */ + pPacket = (HTC_PACKET *) (A_NETBUF_HEAD(osBuf)); + /* set re-fill info */ + SET_HTC_PACKET_INFO_RX_REFILL(pPacket, osBuf, + qdf_nbuf_data(osBuf), + AR6000_BUFFER_SIZE, Endpoint); + SET_HTC_PACKET_NET_BUF_CONTEXT(pPacket, osBuf); + /* add to queue */ + HTC_PACKET_ENQUEUE(&queue, pPacket); + } + + if (!HTC_QUEUE_EMPTY(&queue)) { + /* add packets */ + htc_add_receive_pkt_multiple(pEpping_ctx->HTCHandle, &queue); + } +} +#endif /* HIF_SDIO */ + +void epping_rx(void *ctx, HTC_PACKET *pPacket) +{ + epping_context_t *pEpping_ctx = (epping_context_t *) ctx; + epping_adapter_t *pAdapter = pEpping_ctx->epping_adapter; + struct net_device *dev = pAdapter->dev; + A_STATUS status = pPacket->Status; + HTC_ENDPOINT_ID eid = pPacket->Endpoint; + struct sk_buff *pktSkb = (struct sk_buff *)pPacket->pPktContext; + + EPPING_LOG(QDF_TRACE_LEVEL_INFO, + "%s: pAdapter = 0x%p eid=%d, skb=0x%p, data=0x%p, len=0x%x status:%d", + __func__, pAdapter, eid, pktSkb, pPacket->pBuffer, + pPacket->ActualLength, status); + + if (status != A_OK) { + if (status != A_ECANCELED) { + printk("%s: RX ERR (%d)\n", __func__, status); + } + qdf_nbuf_free(pktSkb); + return; + } + + /* deliver to up layer */ + if (pktSkb) { + if (EPPING_ALIGNMENT_PAD > 0) { + A_NETBUF_PULL(pktSkb, EPPING_ALIGNMENT_PAD); + } + if (enb_rx_dump) + epping_hex_dump((void *)qdf_nbuf_data(pktSkb), + pktSkb->len, __func__); + pktSkb->dev = dev; + if ((pktSkb->dev->flags & IFF_UP) == IFF_UP) { + pktSkb->protocol = eth_type_trans(pktSkb, pktSkb->dev); + ++pAdapter->stats.rx_packets; + pAdapter->stats.rx_bytes += pktSkb->len; + qdf_net_buf_debug_release_skb(pktSkb); + if (hdd_napi_enabled(HDD_NAPI_ANY)) + netif_receive_skb(pktSkb); + else + netif_rx_ni(pktSkb); + if ((pAdapter->stats.rx_packets % + EPPING_STATS_LOG_COUNT) == 0) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: total_rx_pkts = %lu", + __func__, + pAdapter->stats.rx_packets); + } + } else { + ++pAdapter->stats.rx_dropped; + qdf_nbuf_free(pktSkb); + } + } +} diff --git a/utils/epping/src/epping_tx.c b/utils/epping/src/epping_tx.c new file mode 100644 index 0000000000..059de2f637 --- /dev/null +++ b/utils/epping/src/epping_tx.c @@ -0,0 +1,405 @@ +/* + * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*======================================================================== + + \file epping_tx.c + + \brief WLAN End Point Ping test tool implementation + + ========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "epping_main.h" +#include "epping_internal.h" +#include "epping_test.h" + +#define TX_RETRY_TIMEOUT_IN_MS 1 + +static bool enb_tx_dump; + +void epping_tx_dup_pkt(epping_adapter_t *pAdapter, + HTC_ENDPOINT_ID eid, qdf_nbuf_t skb) +{ + struct epping_cookie *cookie = NULL; + int skb_len, ret; + qdf_nbuf_t new_skb; + + cookie = epping_alloc_cookie(pAdapter->pEpping_ctx); + if (cookie == NULL) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: epping_alloc_cookie returns no resource\n", + __func__); + return; + } + new_skb = qdf_nbuf_copy(skb); + if (!new_skb) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: qdf_nbuf_copy returns no resource\n", __func__); + epping_free_cookie(pAdapter->pEpping_ctx, cookie); + return; + } + SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt, + cookie, qdf_nbuf_data(skb), + qdf_nbuf_len(new_skb), eid, 0); + SET_HTC_PACKET_NET_BUF_CONTEXT(&cookie->HtcPkt, new_skb); + skb_len = (int)qdf_nbuf_len(new_skb); + /* send the packet */ + ret = htc_send_pkt(pAdapter->pEpping_ctx->HTCHandle, &cookie->HtcPkt); + if (ret != A_OK) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: htc_send_pkt failed, ret = %d\n", __func__, ret); + epping_free_cookie(pAdapter->pEpping_ctx, cookie); + qdf_nbuf_free(new_skb); + return; + } + pAdapter->stats.tx_bytes += skb_len; + ++pAdapter->stats.tx_packets; + if (((pAdapter->stats.tx_packets + + pAdapter->stats.tx_dropped) % EPPING_STATS_LOG_COUNT) == 0 && + (pAdapter->stats.tx_packets || pAdapter->stats.tx_dropped)) { + epping_log_stats(pAdapter, __func__); + } +} + +static int epping_tx_send_int(qdf_nbuf_t skb, epping_adapter_t *pAdapter) +{ + EPPING_HEADER *eppingHdr = (EPPING_HEADER *) qdf_nbuf_data(skb); + HTC_ENDPOINT_ID eid = ENDPOINT_UNUSED; + struct epping_cookie *cookie = NULL; + A_UINT8 ac = 0; + A_STATUS ret = A_OK; + int skb_len; + EPPING_HEADER tmpHdr = *eppingHdr; + + /* allocate resource for this packet */ + cookie = epping_alloc_cookie(pAdapter->pEpping_ctx); + /* no resource */ + if (cookie == NULL) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: epping_alloc_cookie returns no resource\n", + __func__); + return A_ERROR; + } + + if (enb_tx_dump) + epping_hex_dump((void *)eppingHdr, skb->len, __func__); + /* + * a quirk of linux, the payload of the frame is 32-bit aligned and thus + * the addition of the HTC header will mis-align the start of the HTC + * frame, so we add some padding which will be stripped off in the target + */ + if (EPPING_ALIGNMENT_PAD > 0) { + A_NETBUF_PUSH(skb, EPPING_ALIGNMENT_PAD); + } + /* prepare ep/HTC information */ + ac = eppingHdr->StreamNo_h; + eid = pAdapter->pEpping_ctx->EppingEndpoint[ac]; + if (eid < 0 || eid >= EPPING_MAX_NUM_EPIDS) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: invalid eid = %d, ac = %d\n", __func__, eid, + ac); + return A_ERROR; + } + if (tmpHdr.Cmd_h == EPPING_CMD_RESET_RECV_CNT || + tmpHdr.Cmd_h == EPPING_CMD_CONT_RX_START) { + epping_set_kperf_flag(pAdapter, eid, tmpHdr.CmdBuffer_t[0]); + } + SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt, + cookie, qdf_nbuf_data(skb), qdf_nbuf_len(skb), + eid, 0); + SET_HTC_PACKET_NET_BUF_CONTEXT(&cookie->HtcPkt, skb); + skb_len = skb->len; + /* send the packet */ + ret = htc_send_pkt(pAdapter->pEpping_ctx->HTCHandle, &cookie->HtcPkt); + epping_log_packet(pAdapter, &tmpHdr, ret, __func__); + if (ret != A_OK) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: htc_send_pkt failed, status = %d\n", __func__, + ret); + epping_free_cookie(pAdapter->pEpping_ctx, cookie); + return A_ERROR; + } + pAdapter->stats.tx_bytes += skb_len; + ++pAdapter->stats.tx_packets; + if (((pAdapter->stats.tx_packets + + pAdapter->stats.tx_dropped) % EPPING_STATS_LOG_COUNT) == 0 && + (pAdapter->stats.tx_packets || pAdapter->stats.tx_dropped)) { + epping_log_stats(pAdapter, __func__); + } + + return 0; +} + +void epping_tx_timer_expire(epping_adapter_t *pAdapter) +{ + qdf_nbuf_t nodrop_skb; + + EPPING_LOG(QDF_TRACE_LEVEL_INFO, "%s: queue len: %d\n", __func__, + qdf_nbuf_queue_len(&pAdapter->nodrop_queue)); + + if (!qdf_nbuf_queue_len(&pAdapter->nodrop_queue)) { + /* nodrop queue is empty so no need to arm timer */ + pAdapter->epping_timer_state = EPPING_TX_TIMER_STOPPED; + return; + } + + /* try to flush nodrop queue */ + while ((nodrop_skb = qdf_nbuf_queue_remove(&pAdapter->nodrop_queue))) { + htc_set_nodrop_pkt(pAdapter->pEpping_ctx->HTCHandle, true); + if (epping_tx_send_int(nodrop_skb, pAdapter)) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: nodrop: %p xmit fail in timer\n", + __func__, nodrop_skb); + /* fail to xmit so put the nodrop packet to the nodrop queue */ + qdf_nbuf_queue_insert_head(&pAdapter->nodrop_queue, + nodrop_skb); + break; + } else { + htc_set_nodrop_pkt(pAdapter->pEpping_ctx->HTCHandle, false); + EPPING_LOG(QDF_TRACE_LEVEL_INFO, + "%s: nodrop: %p xmit ok in timer\n", + __func__, nodrop_skb); + } + } + + /* if nodrop queue is not empty, continue to arm timer */ + if (nodrop_skb) { + qdf_spin_lock_bh(&pAdapter->data_lock); + /* if nodrop queue is not empty, continue to arm timer */ + if (pAdapter->epping_timer_state != EPPING_TX_TIMER_RUNNING) { + pAdapter->epping_timer_state = EPPING_TX_TIMER_RUNNING; + qdf_timer_mod(&pAdapter->epping_timer, + TX_RETRY_TIMEOUT_IN_MS); + } + qdf_spin_unlock_bh(&pAdapter->data_lock); + } else { + pAdapter->epping_timer_state = EPPING_TX_TIMER_STOPPED; + } +} + +int epping_tx_send(qdf_nbuf_t skb, epping_adapter_t *pAdapter) +{ + qdf_nbuf_t nodrop_skb; + EPPING_HEADER *eppingHdr; + A_UINT8 ac = 0; + + eppingHdr = (EPPING_HEADER *) qdf_nbuf_data(skb); + + if (!IS_EPPING_PACKET(eppingHdr)) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: Recived non endpoint ping packets\n", __func__); + /* no packet to send, cleanup */ + qdf_nbuf_free(skb); + return -ENOMEM; + } + + /* the stream ID is mapped to an access class */ + ac = eppingHdr->StreamNo_h; + /* hard coded two ep ids */ + if (ac != 0 && ac != 1) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: ac %d is not mapped to mboxping service\n", + __func__, ac); + qdf_nbuf_free(skb); + return -ENOMEM; + } + + /* + * some EPPING packets cannot be dropped no matter what access class + * it was sent on. A special care has been taken: + * 1. when there is no TX resource, queue the control packets to + * a special queue + * 2. when there is TX resource, send the queued control packets first + * and then other packets + * 3. a timer launches to check if there is queued control packets and + * flush them + */ + + /* check the nodrop queue first */ + while ((nodrop_skb = qdf_nbuf_queue_remove(&pAdapter->nodrop_queue))) { + htc_set_nodrop_pkt(pAdapter->pEpping_ctx->HTCHandle, true); + if (epping_tx_send_int(nodrop_skb, pAdapter)) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: nodrop: %p xmit fail\n", __func__, + nodrop_skb); + /* fail to xmit so put the nodrop packet to the nodrop queue */ + qdf_nbuf_queue_insert_head(&pAdapter->nodrop_queue, + nodrop_skb); + /* no cookie so free the current skb */ + goto tx_fail; + } else { + htc_set_nodrop_pkt(pAdapter->pEpping_ctx->HTCHandle, false); + EPPING_LOG(QDF_TRACE_LEVEL_INFO, + "%s: nodrop: %p xmit ok\n", __func__, + nodrop_skb); + } + } + + /* send the original packet */ + if (epping_tx_send_int(skb, pAdapter)) + goto tx_fail; + + return 0; + +tx_fail: + if (!IS_EPING_PACKET_NO_DROP(eppingHdr)) { + /* allow to drop the skb so drop it */ + qdf_nbuf_free(skb); + ++pAdapter->stats.tx_dropped; + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: Tx skb %p dropped, stats.tx_dropped = %ld\n", + __func__, skb, pAdapter->stats.tx_dropped); + return -ENOMEM; + } else { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: nodrop: %p queued\n", __func__, skb); + qdf_nbuf_queue_add(&pAdapter->nodrop_queue, skb); + qdf_spin_lock_bh(&pAdapter->data_lock); + if (pAdapter->epping_timer_state != EPPING_TX_TIMER_RUNNING) { + pAdapter->epping_timer_state = EPPING_TX_TIMER_RUNNING; + qdf_timer_mod(&pAdapter->epping_timer, + TX_RETRY_TIMEOUT_IN_MS); + } + qdf_spin_unlock_bh(&pAdapter->data_lock); + } + + return 0; +} + +#ifdef HIF_SDIO +HTC_SEND_FULL_ACTION epping_tx_queue_full(void *Context, HTC_PACKET *pPacket) +{ + /* + * Call netif_stop_queue frequently will impact the mboxping tx t-put. + * Return HTC_SEND_FULL_KEEP directly in epping_tx_queue_full to avoid. + */ + return HTC_SEND_FULL_KEEP; +} +#endif /* HIF_SDIO */ +void epping_tx_complete_multiple(void *ctx, HTC_PACKET_QUEUE *pPacketQueue) +{ + epping_context_t *pEpping_ctx = (epping_context_t *) ctx; + epping_adapter_t *pAdapter = pEpping_ctx->epping_adapter; + struct net_device *dev = pAdapter->dev; + A_STATUS status; + HTC_ENDPOINT_ID eid; + qdf_nbuf_t pktSkb; + struct epping_cookie *cookie; + A_BOOL flushing = false; + qdf_nbuf_queue_t skb_queue; + HTC_PACKET *htc_pkt; + + qdf_nbuf_queue_init(&skb_queue); + + qdf_spin_lock_bh(&pAdapter->data_lock); + + while (!HTC_QUEUE_EMPTY(pPacketQueue)) { + htc_pkt = htc_packet_dequeue(pPacketQueue); + if (htc_pkt == NULL) + break; + status = htc_pkt->Status; + eid = htc_pkt->Endpoint; + pktSkb = GET_HTC_PACKET_NET_BUF_CONTEXT(htc_pkt); + cookie = htc_pkt->pPktContext; + + if (!pktSkb) { + EPPING_LOG(QDF_TRACE_LEVEL_ERROR, + "%s: NULL skb from hc packet", __func__); + QDF_BUG(0); + } else { + if (htc_pkt->pBuffer != qdf_nbuf_data(pktSkb)) { + EPPING_LOG(QDF_TRACE_LEVEL_ERROR, + "%s: htc_pkt buffer not equal to skb->data", + __func__); + QDF_BUG(0); + } + /* add this to the list, use faster non-lock API */ + qdf_nbuf_queue_add(&skb_queue, pktSkb); + + if (A_SUCCESS(status)) { + if (htc_pkt->ActualLength != + qdf_nbuf_len(pktSkb)) { + EPPING_LOG(QDF_TRACE_LEVEL_ERROR, + "%s: htc_pkt length not equal to skb->len", + __func__); + QDF_BUG(0); + } + } + } + + EPPING_LOG(QDF_TRACE_LEVEL_INFO, + "%s skb=%p data=%p len=0x%x eid=%d ", + __func__, pktSkb, htc_pkt->pBuffer, + htc_pkt->ActualLength, eid); + + if (A_FAILED(status)) { + if (status == A_ECANCELED) { + /* a packet was flushed */ + flushing = true; + } + if (status != A_NO_RESOURCE) { + printk("%s() -TX ERROR, status: 0x%x\n", + __func__, status); + } + } else { + EPPING_LOG(QDF_TRACE_LEVEL_INFO, "%s: OK\n", __func__); + flushing = false; + } + + epping_free_cookie(pAdapter->pEpping_ctx, cookie); + } + + qdf_spin_unlock_bh(&pAdapter->data_lock); + + /* free all skbs in our local list */ + while (qdf_nbuf_queue_len(&skb_queue)) { + /* use non-lock version */ + pktSkb = qdf_nbuf_queue_remove(&skb_queue); + if (pktSkb == NULL) + break; + qdf_nbuf_tx_free(pktSkb, QDF_NBUF_PKT_ERROR); + pEpping_ctx->total_tx_acks++; + } + + if (!flushing) { + netif_wake_queue(dev); + } +} diff --git a/utils/epping/src/epping_txrx.c b/utils/epping/src/epping_txrx.c new file mode 100644 index 0000000000..4b58890009 --- /dev/null +++ b/utils/epping/src/epping_txrx.c @@ -0,0 +1,470 @@ +/* + * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*======================================================================== + + \file epping_txrx.c + + \brief WLAN End Point Ping test tool implementation + + ========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "epping_main.h" +#include "epping_internal.h" + +static int epping_start_adapter(epping_adapter_t *pAdapter); +static void epping_stop_adapter(epping_adapter_t *pAdapter); + +static void epping_timer_expire(void *data) +{ + struct net_device *dev = (struct net_device *)data; + epping_adapter_t *pAdapter; + + if (dev == NULL) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: netdev = NULL", __func__); + return; + } + + pAdapter = netdev_priv(dev); + if (pAdapter == NULL) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: adapter = NULL", __func__); + return; + } + pAdapter->epping_timer_state = EPPING_TX_TIMER_STOPPED; + epping_tx_timer_expire(pAdapter); +} + +static int epping_ndev_open(struct net_device *dev) +{ + epping_adapter_t *pAdapter; + int ret = 0; + + pAdapter = netdev_priv(dev); + epping_start_adapter(pAdapter); + return ret; +} + +static int epping_ndev_stop(struct net_device *dev) +{ + epping_adapter_t *pAdapter; + int ret = 0; + + pAdapter = netdev_priv(dev); + if (NULL == pAdapter) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: EPPING adapter context is Null", __func__); + ret = -ENODEV; + goto end; + } + epping_stop_adapter(pAdapter); +end: + return ret; +} + +static void epping_ndev_uninit(struct net_device *dev) +{ + epping_adapter_t *pAdapter; + + pAdapter = netdev_priv(dev); + if (NULL == pAdapter) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: EPPING adapter context is Null", __func__); + goto end; + } + epping_stop_adapter(pAdapter); +end: + return; +} + +static void epping_tx_queue_timeout(struct net_device *dev) +{ + epping_adapter_t *pAdapter; + + pAdapter = netdev_priv(dev); + if (NULL == pAdapter) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: EPPING adapter context is Null", __func__); + goto end; + } + + EPPING_LOG(QDF_TRACE_LEVEL_ERROR, + "%s: Transmission timeout occurred, pAdapter->started= %d", + __func__, pAdapter->started); + + /* Getting here implies we disabled the TX queues + * for too long. Since this is epping + * (not because of disassociation or low resource scenarios), + * try to restart the queue + */ + if (pAdapter->started) + netif_wake_queue(dev); +end: + return; + +} + +static int epping_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + epping_adapter_t *pAdapter; + int ret = 0; + + pAdapter = netdev_priv(dev); + if (NULL == pAdapter) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: EPPING adapter context is Null", __func__); + ret = -ENODEV; + goto end; + } + ret = epping_tx_send(skb, pAdapter); +end: + return ret; +} + +static struct net_device_stats *epping_get_stats(struct net_device *dev) +{ + epping_adapter_t *pAdapter = netdev_priv(dev); + + if (NULL == pAdapter) { + EPPING_LOG(QDF_TRACE_LEVEL_ERROR, "%s: pAdapter = NULL", + __func__); + return NULL; + } + + return &pAdapter->stats; +} + +static int epping_ndev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + epping_adapter_t *pAdapter; + int ret = 0; + + pAdapter = netdev_priv(dev); + if (NULL == pAdapter) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: EPPING adapter context is Null", __func__); + ret = -ENODEV; + goto end; + } + if (dev != pAdapter->dev) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: HDD adapter/dev inconsistency", __func__); + ret = -ENODEV; + goto end; + } + + if ((!ifr) || (!ifr->ifr_data)) { + ret = -EINVAL; + goto end; + } + + switch (cmd) { + case (SIOCDEVPRIVATE + 1): + EPPING_LOG(QDF_TRACE_LEVEL_ERROR, + "%s: do not support ioctl %d (SIOCDEVPRIVATE + 1)", + __func__, cmd); + break; + default: + EPPING_LOG(QDF_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d", + __func__, cmd); + ret = -EINVAL; + break; + } + +end: + return ret; +} + +static int epping_set_mac_address(struct net_device *dev, void *addr) +{ + epping_adapter_t *pAdapter = netdev_priv(dev); + struct sockaddr *psta_mac_addr = addr; + qdf_mem_copy(&pAdapter->macAddressCurrent, + psta_mac_addr->sa_data, ETH_ALEN); + qdf_mem_copy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN); + return 0; +} + +static void epping_stop_adapter(epping_adapter_t *pAdapter) +{ + qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); + + if (!qdf_ctx) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: qdf_ctx is NULL\n", __func__); + return; + } + + if (pAdapter && pAdapter->started) { + EPPING_LOG(LOG1, FL("Disabling queues")); + netif_tx_disable(pAdapter->dev); + netif_carrier_off(pAdapter->dev); + pAdapter->started = false; + pld_request_bus_bandwidth(qdf_ctx->dev, + PLD_BUS_WIDTH_LOW); + } +} + +static int epping_start_adapter(epping_adapter_t *pAdapter) +{ + qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); + + if (!qdf_ctx) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: qdf_ctx is NULL", __func__); + return -EINVAL; + } + + if (!pAdapter) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: pAdapter= NULL\n", __func__); + return -EINVAL; + } + if (!pAdapter->started) { + pld_request_bus_bandwidth(qdf_ctx->dev, + PLD_BUS_WIDTH_HIGH); + netif_carrier_on(pAdapter->dev); + EPPING_LOG(LOG1, FL("Enabling queues")); + netif_tx_start_all_queues(pAdapter->dev); + pAdapter->started = true; + } else { + EPPING_LOG(QDF_TRACE_LEVEL_WARN, + "%s: pAdapter %p already started\n", __func__, + pAdapter); + } + return 0; +} + +static int epping_register_adapter(epping_adapter_t *pAdapter) +{ + int ret = 0; + + ret = register_netdev(pAdapter->dev); + if (ret != 0) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: unable to register device\n", + pAdapter->dev->name); + } else { + pAdapter->registered = true; + } + return ret; +} + +static void epping_unregister_adapter(epping_adapter_t *pAdapter) +{ + if (pAdapter) { + epping_stop_adapter(pAdapter); + if (pAdapter->registered) { + unregister_netdev(pAdapter->dev); + pAdapter->registered = false; + } + } else { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: pAdapter = NULL, unable to unregister device\n", + __func__); + } +} + +void epping_destroy_adapter(epping_adapter_t *pAdapter) +{ + struct net_device *dev = NULL; + epping_context_t *pEpping_ctx; + + if (!pAdapter || !pAdapter->pEpping_ctx) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: pAdapter = NULL\n", __func__); + return; + } + + dev = pAdapter->dev; + pEpping_ctx = pAdapter->pEpping_ctx; + epping_unregister_adapter(pAdapter); + + qdf_spinlock_destroy(&pAdapter->data_lock); + qdf_timer_free(&pAdapter->epping_timer); + pAdapter->epping_timer_state = EPPING_TX_TIMER_STOPPED; + + while (qdf_nbuf_queue_len(&pAdapter->nodrop_queue)) { + qdf_nbuf_t tmp_nbuf = NULL; + tmp_nbuf = qdf_nbuf_queue_remove(&pAdapter->nodrop_queue); + if (tmp_nbuf) + qdf_nbuf_free(tmp_nbuf); + } + + free_netdev(dev); + if (!pEpping_ctx) + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: pEpping_ctx = NULL\n", __func__); + else + pEpping_ctx->epping_adapter = NULL; +} + +static struct net_device_ops epping_drv_ops = { + .ndo_open = epping_ndev_open, + .ndo_stop = epping_ndev_stop, + .ndo_uninit = epping_ndev_uninit, + .ndo_start_xmit = epping_hard_start_xmit, + .ndo_tx_timeout = epping_tx_queue_timeout, + .ndo_get_stats = epping_get_stats, + .ndo_do_ioctl = epping_ndev_ioctl, + .ndo_set_mac_address = epping_set_mac_address, + .ndo_select_queue = NULL, +}; + +#define EPPING_TX_QUEUE_MAX_LEN 128 /* need to be power of 2 */ + +epping_adapter_t *epping_add_adapter(epping_context_t *pEpping_ctx, + tSirMacAddr macAddr, + enum tQDF_ADAPTER_MODE device_mode) +{ + struct net_device *dev; + epping_adapter_t *pAdapter; + + dev = alloc_netdev(sizeof(epping_adapter_t), "wifi%d", +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) + NET_NAME_UNKNOWN, +#endif + ether_setup); + if (dev == NULL) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "%s: Cannot allocate epping_adapter_t\n", __func__); + return NULL; + } + + pAdapter = netdev_priv(dev); + qdf_mem_zero(pAdapter, sizeof(*pAdapter)); + pAdapter->dev = dev; + pAdapter->pEpping_ctx = pEpping_ctx; + pAdapter->device_mode = device_mode; /* station, SAP, etc */ + qdf_mem_copy(dev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr)); + qdf_mem_copy(pAdapter->macAddressCurrent.bytes, + macAddr, sizeof(tSirMacAddr)); + qdf_spinlock_create(&pAdapter->data_lock); + qdf_nbuf_queue_init(&pAdapter->nodrop_queue); + pAdapter->epping_timer_state = EPPING_TX_TIMER_STOPPED; + qdf_timer_init(epping_get_qdf_ctx(), &pAdapter->epping_timer, + epping_timer_expire, dev, QDF_TIMER_TYPE_SW); + dev->type = ARPHRD_IEEE80211; + dev->netdev_ops = &epping_drv_ops; + dev->watchdog_timeo = 5 * HZ; /* XXX */ + dev->tx_queue_len = EPPING_TXBUF - 1; /* 1 for mgmt frame */ + if (epping_register_adapter(pAdapter) == 0) { + EPPING_LOG(LOG1, FL("Disabling queues")); + netif_tx_disable(dev); + netif_carrier_off(dev); + return pAdapter; + } else { + epping_destroy_adapter(pAdapter); + return NULL; + } +} + +int epping_connect_service(epping_context_t *pEpping_ctx) +{ + int status, i; + HTC_SERVICE_CONNECT_REQ connect; + HTC_SERVICE_CONNECT_RESP response; + + qdf_mem_zero(&connect, sizeof(connect)); + qdf_mem_zero(&response, sizeof(response)); + + /* these fields are the same for all service endpoints */ + connect.EpCallbacks.pContext = pEpping_ctx; + connect.EpCallbacks.EpTxCompleteMultiple = epping_tx_complete_multiple; + connect.EpCallbacks.EpRecv = epping_rx; + /* epping_tx_complete use Multiple version */ + connect.EpCallbacks.EpTxComplete = NULL; + connect.MaxSendQueueDepth = 64; + +#ifdef HIF_SDIO + connect.EpCallbacks.EpRecvRefill = epping_refill; + connect.EpCallbacks.EpSendFull = + epping_tx_queue_full /* ar6000_tx_queue_full */; +#elif defined(HIF_USB) || defined(HIF_PCI) + connect.EpCallbacks.EpRecvRefill = NULL /* provided by HIF */; + connect.EpCallbacks.EpSendFull = NULL /* provided by HIF */; + /* disable flow control for hw flow control */ + connect.ConnectionFlags |= HTC_CONNECT_FLAGS_DISABLE_CREDIT_FLOW_CTRL; +#endif + + /* connect to service */ + connect.service_id = WMI_DATA_BE_SVC; + status = htc_connect_service(pEpping_ctx->HTCHandle, &connect, &response); + if (status != EOK) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "Failed to connect to Endpoint Ping BE service status:%d\n", + status); + return status; + } else { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "eppingtest BE endpoint:%d\n", response.Endpoint); + } + pEpping_ctx->EppingEndpoint[0] = response.Endpoint; + +#if defined(HIF_PCI) || defined(HIF_USB) + connect.service_id = WMI_DATA_BK_SVC; + status = htc_connect_service(pEpping_ctx->HTCHandle, &connect, &response); + if (status != EOK) { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "Failed to connect to Endpoint Ping BK service status:%d\n", + status); + return status; + } else { + EPPING_LOG(QDF_TRACE_LEVEL_FATAL, + "eppingtest BK endpoint:%d\n", response.Endpoint); + } + pEpping_ctx->EppingEndpoint[1] = response.Endpoint; + /* Since we do not create other two SVC use BK endpoint + * for rest ACs (2, 3) */ + for (i = 2; i < EPPING_MAX_NUM_EPIDS; i++) { + pEpping_ctx->EppingEndpoint[i] = response.Endpoint; + } +#else + /* we only use one endpoint for high latenance bus. + * Map all AC's EPIDs to the same endpoint ID returned by HTC */ + for (i = 0; i < EPPING_MAX_NUM_EPIDS; i++) { + pEpping_ctx->EppingEndpoint[i] = response.Endpoint; + } +#endif + return 0; +} diff --git a/utils/fwlog/dbglog_host.c b/utils/fwlog/dbglog_host.c new file mode 100644 index 0000000000..6fb609148b --- /dev/null +++ b/utils/fwlog/dbglog_host.c @@ -0,0 +1,4394 @@ +/* + * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* Host Debug log implementation */ + +#include "athdefs.h" +#include "a_types.h" +#include "dbglog_host.h" +#include "wmi.h" +#include "wmi_unified_api.h" +#include "wma.h" +#include "ol_defines.h" +#include +#include "host_diag_core_event.h" +#include "qwlan_version.h" +#include +#include +#include + +#ifdef WLAN_OPEN_SOURCE +#include +#endif /* WLAN_OPEN_SOURCE */ +#include "wmi_unified_priv.h" + +#ifdef MULTI_IF_NAME +#define CLD_DEBUGFS_DIR "cld" MULTI_IF_NAME +#else + +#define CLD_DEBUGFS_DIR "cld" +#endif +#define DEBUGFS_BLOCK_NAME "dbglog_block" + +#define ATH_MODULE_NAME fwlog +#include +#define FWLOG_DEBUG ATH_DEBUG_MAKE_MODULE_MASK(0) + +#ifdef WLAN_DEBUG + +static int get_version; +static int gprint_limiter; + +static ATH_DEBUG_MASK_DESCRIPTION g_fwlog_debug_description[] = { + {FWLOG_DEBUG, "fwlog"}, +}; + +ATH_DEBUG_INSTANTIATE_MODULE_VAR(fwlog, + "fwlog", + "Firmware Debug Log", + ATH_DEBUG_MASK_DEFAULTS | ATH_DEBUG_INFO | + ATH_DEBUG_ERR, + ATH_DEBUG_DESCRIPTION_COUNT + (g_fwlog_debug_description), + g_fwlog_debug_description); +#endif + +module_dbg_print mod_print[WLAN_MODULE_ID_MAX]; + +A_UINT32 dbglog_process_type = DBGLOG_PROCESS_NET_RAW; + +static const char *dbglog_get_module_str(A_UINT32 module_id) +{ + switch (module_id) { + case WLAN_MODULE_INF: + return "INF"; + case WLAN_MODULE_WMI: + return "WMI"; + case WLAN_MODULE_STA_PWRSAVE: + return "STA PS"; + case WLAN_MODULE_WHAL: + return "WHAL"; + case WLAN_MODULE_COEX: + return "COEX"; + case WLAN_MODULE_ROAM: + return "ROAM"; + case WLAN_MODULE_RESMGR_CHAN_MANAGER: + return "CHANMGR"; + case WLAN_MODULE_RESMGR: + return "RESMGR"; + case WLAN_MODULE_VDEV_MGR: + return "VDEV"; + case WLAN_MODULE_SCAN: + return "SCAN"; + case WLAN_MODULE_RATECTRL: + return "RC"; + case WLAN_MODULE_AP_PWRSAVE: + return "AP PS"; + case WLAN_MODULE_BLOCKACK: + return "BA"; + case WLAN_MODULE_MGMT_TXRX: + return "MGMT"; + case WLAN_MODULE_DATA_TXRX: + return "DATA"; + case WLAN_MODULE_HTT: + return "HTT"; + case WLAN_MODULE_HOST: + return "HOST"; + case WLAN_MODULE_BEACON: + return "BEACON"; + case WLAN_MODULE_OFFLOAD: + return "OFFLOAD"; + case WLAN_MODULE_WAL: + return "WAL"; + case WAL_MODULE_DE: + return "DE"; + case WLAN_MODULE_PCIELP: + return "PCIELP"; + case WLAN_MODULE_RTT: + return "RTT"; + case WLAN_MODULE_DCS: + return "DCS"; + case WLAN_MODULE_CACHEMGR: + return "CACHEMGR"; + case WLAN_MODULE_ANI: + return "ANI"; + case WLAN_MODULE_TEST: + return "TESTPOINT"; + case WLAN_MODULE_STA_SMPS: + return "STA_SMPS"; + case WLAN_MODULE_TDLS: + return "TDLS"; + case WLAN_MODULE_P2P: + return "P2P"; + case WLAN_MODULE_WOW: + return "WoW"; + case WLAN_MODULE_IBSS_PWRSAVE: + return "IBSS PS"; + case WLAN_MODULE_EXTSCAN: + return "ExtScan"; + case WLAN_MODULE_UNIT_TEST: + return "UNIT_TEST"; + case WLAN_MODULE_MLME: + return "MLME"; + case WLAN_MODULE_SUPPL: + return "SUPPLICANT"; + default: + return "UNKNOWN"; + } +} + +char *DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] = { + { + "INF_MSG_START", + "INF_ASSERTION_FAILED", + "INF_TARGET_ID", + "INF_MSG_END" + }, + { + "WMI_DBGID_DEFINITION_START", + "WMI_CMD_RX_XTND_PKT_TOO_SHORT", + "WMI_EXTENDED_CMD_NOT_HANDLED", + "WMI_CMD_RX_PKT_TOO_SHORT", + "WMI_CALLING_WMI_EXTENSION_FN", + "WMI_CMD_NOT_HANDLED", + "WMI_IN_SYNC", + "WMI_TARGET_WMI_SYNC_CMD", + "WMI_SET_SNR_THRESHOLD_PARAMS", + "WMI_SET_RSSI_THRESHOLD_PARAMS", + "WMI_SET_LQ_TRESHOLD_PARAMS", + "WMI_TARGET_CREATE_PSTREAM_CMD", + "WMI_WI_DTM_INUSE", + "WMI_TARGET_DELETE_PSTREAM_CMD", + "WMI_TARGET_IMPLICIT_DELETE_PSTREAM_CMD", + "WMI_TARGET_GET_BIT_RATE_CMD", + "WMI_GET_RATE_MASK_CMD_FIX_RATE_MASK_IS", + "WMI_TARGET_GET_AVAILABLE_CHANNELS_CMD", + "WMI_TARGET_GET_TX_PWR_CMD", + "WMI_FREE_EVBUF_WMIBUF", + "WMI_FREE_EVBUF_DATABUF", + "WMI_FREE_EVBUF_BADFLAG", + "WMI_HTC_RX_ERROR_DATA_PACKET", + "WMI_HTC_RX_SYNC_PAUSING_FOR_MBOX", + "WMI_INCORRECT_WMI_DATA_HDR_DROPPING_PKT", + "WMI_SENDING_READY_EVENT", + "WMI_SETPOWER_MDOE_TO_MAXPERF", + "WMI_SETPOWER_MDOE_TO_REC", + "WMI_BSSINFO_EVENT_FROM", + "WMI_TARGET_GET_STATS_CMD", + "WMI_SENDING_SCAN_COMPLETE_EVENT", + "WMI_SENDING_RSSI_INDB_THRESHOLD_EVENT ", + "WMI_SENDING_RSSI_INDBM_THRESHOLD_EVENT", + "WMI_SENDING_LINK_QUALITY_THRESHOLD_EVENT", + "WMI_SENDING_ERROR_REPORT_EVENT", + "WMI_SENDING_CAC_EVENT", + "WMI_TARGET_GET_ROAM_TABLE_CMD", + "WMI_TARGET_GET_ROAM_DATA_CMD", + "WMI_SENDING_GPIO_INTR_EVENT", + "WMI_SENDING_GPIO_ACK_EVENT", + "WMI_SENDING_GPIO_DATA_EVENT", + "WMI_CMD_RX", + "WMI_CMD_RX_XTND", + "WMI_EVENT_SEND", + "WMI_EVENT_SEND_XTND", + "WMI_CMD_PARAMS_DUMP_START", + "WMI_CMD_PARAMS_DUMP_END", + "WMI_CMD_PARAMS", + "WMI_EVENT_ALLOC_FAILURE", + "WMI_DBGID_DCS_PARAM_CMD", + "WMI_SEND_EVENT_WRONG_TLV", + "WMI_SEND_EVENT_NO_TLV_DEF", + "WMI_DBGID_DEFNITION_END", + }, + { + "PS_STA_DEFINITION_START", + "PS_STA_PM_ARB_REQUEST", + "PS_STA_DELIVER_EVENT", + "PS_STA_PSPOLL_SEQ_DONE", + "PS_STA_COEX_MODE", + "PS_STA_PSPOLL_ALLOW", + "PS_STA_SET_PARAM", + "PS_STA_SPECPOLL_TIMER_STARTED", + "PS_STA_SPECPOLL_TIMER_STOPPED", + }, + { + "WHAL_DBGID_DEFINITION_START", + "WHAL_ERROR_ANI_CONTROL", + "WHAL_ERROR_CHIP_TEST1", + "WHAL_ERROR_CHIP_TEST2", + "WHAL_ERROR_EEPROM_CHECKSUM", + "WHAL_ERROR_EEPROM_MACADDR", + "WHAL_ERROR_INTERRUPT_HIU", + "WHAL_ERROR_KEYCACHE_RESET", + "WHAL_ERROR_KEYCACHE_SET", + "WHAL_ERROR_KEYCACHE_TYPE", + "WHAL_ERROR_KEYCACHE_TKIPENTRY", + "WHAL_ERROR_KEYCACHE_WEPLENGTH", + "WHAL_ERROR_PHY_INVALID_CHANNEL", + "WHAL_ERROR_POWER_AWAKE", + "WHAL_ERROR_POWER_SET", + "WHAL_ERROR_RECV_STOPDMA", + "WHAL_ERROR_RECV_STOPPCU", + "WHAL_ERROR_RESET_CHANNF1", + "WHAL_ERROR_RESET_CHANNF2", + "WHAL_ERROR_RESET_PM", + "WHAL_ERROR_RESET_OFFSETCAL", + "WHAL_ERROR_RESET_RFGRANT", + "WHAL_ERROR_RESET_RXFRAME", + "WHAL_ERROR_RESET_STOPDMA", + "WHAL_ERROR_RESET_ERRID", + "WHAL_ERROR_RESET_ADCDCCAL1", + "WHAL_ERROR_RESET_ADCDCCAL2", + "WHAL_ERROR_RESET_TXIQCAL", + "WHAL_ERROR_RESET_RXIQCAL", + "WHAL_ERROR_RESET_CARRIERLEAK", + "WHAL_ERROR_XMIT_COMPUTE", + "WHAL_ERROR_XMIT_NOQUEUE", + "WHAL_ERROR_XMIT_ACTIVEQUEUE", + "WHAL_ERROR_XMIT_BADTYPE", + "WHAL_ERROR_XMIT_STOPDMA", + "WHAL_ERROR_INTERRUPT_BB_PANIC", + "WHAL_ERROR_PAPRD_MAXGAIN_ABOVE_WINDOW", + "WHAL_ERROR_QCU_HW_PAUSE_MISMATCH", + "WHAL_DBGID_DEFINITION_END", + }, + { + "COEX_DEBUGID_START", + "BTCOEX_DBG_MCI_1", + "BTCOEX_DBG_MCI_2", + "BTCOEX_DBG_MCI_3", + "BTCOEX_DBG_MCI_4", + "BTCOEX_DBG_MCI_5", + "BTCOEX_DBG_MCI_6", + "BTCOEX_DBG_MCI_7", + "BTCOEX_DBG_MCI_8", + "BTCOEX_DBG_MCI_9", + "BTCOEX_DBG_MCI_10", + "COEX_WAL_BTCOEX_INIT", + "COEX_WAL_PAUSE", + "COEX_WAL_RESUME", + "COEX_UPDATE_AFH", + "COEX_HWQ_EMPTY_CB", + "COEX_MCI_TIMER_HANDLER", + "COEX_MCI_RECOVER", + "ERROR_COEX_MCI_ISR", + "ERROR_COEX_MCI_GPM", + "COEX_ProfileType", + "COEX_LinkID", + "COEX_LinkState", + "COEX_LinkRole", + "COEX_LinkRate", + "COEX_VoiceType", + "COEX_TInterval", + "COEX_WRetrx", + "COEX_Attempts", + "COEX_PerformanceState", + "COEX_LinkType", + "COEX_RX_MCI_GPM_VERSION_QUERY", + "COEX_RX_MCI_GPM_VERSION_RESPONSE", + "COEX_RX_MCI_GPM_STATUS_QUERY", + "COEX_STATE_WLAN_VDEV_DOWN", + "COEX_STATE_WLAN_VDEV_START", + "COEX_STATE_WLAN_VDEV_CONNECTED", + "COEX_STATE_WLAN_VDEV_SCAN_STARTED", + "COEX_STATE_WLAN_VDEV_SCAN_END", + "COEX_STATE_WLAN_DEFAULT", + "COEX_CHANNEL_CHANGE", + "COEX_POWER_CHANGE", + "COEX_CONFIG_MGR", + "COEX_TX_MCI_GPM_BT_CAL_REQ", + "COEX_TX_MCI_GPM_BT_CAL_GRANT", + "COEX_TX_MCI_GPM_BT_CAL_DONE", + "COEX_TX_MCI_GPM_WLAN_CAL_REQ", + "COEX_TX_MCI_GPM_WLAN_CAL_GRANT", + "COEX_TX_MCI_GPM_WLAN_CAL_DONE", + "COEX_TX_MCI_GPM_BT_DEBUG", + "COEX_TX_MCI_GPM_VERSION_QUERY", + "COEX_TX_MCI_GPM_VERSION_RESPONSE", + "COEX_TX_MCI_GPM_STATUS_QUERY", + "COEX_TX_MCI_GPM_HALT_BT_GPM", + "COEX_TX_MCI_GPM_WLAN_CHANNELS", + "COEX_TX_MCI_GPM_BT_PROFILE_INFO", + "COEX_TX_MCI_GPM_BT_STATUS_UPDATE", + "COEX_TX_MCI_GPM_BT_UPDATE_FLAGS", + "COEX_TX_MCI_GPM_UNKNOWN", + "COEX_TX_MCI_SYS_WAKING", + "COEX_TX_MCI_LNA_TAKE", + "COEX_TX_MCI_LNA_TRANS", + "COEX_TX_MCI_SYS_SLEEPING", + "COEX_TX_MCI_REQ_WAKE", + "COEX_TX_MCI_REMOTE_RESET", + "COEX_TX_MCI_TYPE_UNKNOWN", + "COEX_WHAL_MCI_RESET", + "COEX_POLL_BT_CAL_DONE_TIMEOUT", + "COEX_WHAL_PAUSE", + "COEX_RX_MCI_GPM_BT_CAL_REQ", + "COEX_RX_MCI_GPM_BT_CAL_DONE", + "COEX_RX_MCI_GPM_BT_CAL_GRANT", + "COEX_WLAN_CAL_START", + "COEX_WLAN_CAL_RESULT", + "COEX_BtMciState", + "COEX_BtCalState", + "COEX_WlanCalState", + "COEX_RxReqWakeCount", + "COEX_RxRemoteResetCount", + "COEX_RESTART_CAL", + "COEX_SENDMSG_QUEUE", + "COEX_RESETSEQ_LNAINFO_TIMEOUT", + "COEX_MCI_ISR_IntRaw", + "COEX_MCI_ISR_Int1Raw", + "COEX_MCI_ISR_RxMsgRaw", + "COEX_WHAL_COEX_RESET", + "COEX_WAL_COEX_INIT", + "COEX_TXRX_CNT_LIMIT_ISR", + "COEX_CH_BUSY", + "COEX_REASSESS_WLAN_STATE", + "COEX_BTCOEX_WLAN_STATE_UPDATE", + "COEX_BT_NUM_OF_PROFILES", + "COEX_BT_NUM_OF_HID_PROFILES", + "COEX_BT_NUM_OF_ACL_PROFILES", + "COEX_BT_NUM_OF_HI_ACL_PROFILES", + "COEX_BT_NUM_OF_VOICE_PROFILES", + "COEX_WLAN_AGGR_LIMIT", + "COEX_BT_LOW_PRIO_BUDGET", + "COEX_BT_HI_PRIO_BUDGET", + "COEX_BT_IDLE_TIME", + "COEX_SET_COEX_WEIGHT", + "COEX_WLAN_WEIGHT_GROUP", + "COEX_BT_WEIGHT_GROUP", + "COEX_BT_INTERVAL_ALLOC", + "COEX_BT_SCHEME", + "COEX_BT_MGR", + "COEX_BT_SM_ERROR", + "COEX_SYSTEM_UPDATE", + "COEX_LOW_PRIO_LIMIT", + "COEX_HI_PRIO_LIMIT", + "COEX_BT_INTERVAL_START", + "COEX_WLAN_INTERVAL_START", + "COEX_NON_LINK_BUDGET", + "COEX_CONTENTION_MSG", + "COEX_SET_NSS", + "COEX_SELF_GEN_MASK", + "COEX_PROFILE_ERROR", + "COEX_WLAN_INIT", + "COEX_BEACON_MISS", + "COEX_BEACON_OK", + "COEX_BTCOEX_SCAN_ACTIVITY", + "COEX_SCAN_ACTIVITY", + "COEX_FORCE_QUIETTIME", + "COEX_BT_MGR_QUIETTIME", + "COEX_BT_INACTIVITY_TRIGGER", + "COEX_BT_INACTIVITY_REPORTED", + "COEX_TX_MCI_GPM_WLAN_PRIO", + "COEX_TX_MCI_GPM_BT_PAUSE_PROFILE", + "COEX_TX_MCI_GPM_WLAN_SET_ACL_INACTIVITY", + "COEX_RX_MCI_GPM_BT_ACL_INACTIVITY_REPORT", + "COEX_GENERIC_ERROR", + "COEX_RX_RATE_THRESHOLD", + "COEX_RSSI", + "COEX_WLAN_VDEV_NOTIF_START", /* 133 */ + "COEX_WLAN_VDEV_NOTIF_UP", /* 134 */ + "COEX_WLAN_VDEV_NOTIF_DOWN", /* 135 */ + "COEX_WLAN_VDEV_NOTIF_STOP", /* 136 */ + "COEX_WLAN_VDEV_NOTIF_ADD_PEER", /* 137 */ + "COEX_WLAN_VDEV_NOTIF_DELETE_PEER", /* 138 */ + "COEX_WLAN_VDEV_NOTIF_CONNECTED_PEER", /* 139 */ + "COEX_WLAN_VDEV_NOTIF_PAUSE", /* 140 */ + "COEX_WLAN_VDEV_NOTIF_UNPAUSED", /* 141 */ + "COEX_STATE_WLAN_VDEV_PEER_ADD", /* 142 */ + "COEX_STATE_WLAN_VDEV_CONNECTED_PEER", /* 143 */ + "COEX_STATE_WLAN_VDEV_DELETE_PEER", /* 144 */ + "COEX_STATE_WLAN_VDEV_PAUSE", /* 145 */ + "COEX_STATE_WLAN_VDEV_UNPAUSED", /* 146 */ + "COEX_SCAN_CALLBACK", /* 147 */ + "COEX_RC_SET_CHAINMASK", /* 148 */ + "COEX_TX_MCI_GPM_WLAN_SET_BT_RXSS_THRES", /* 149 */ + "COEX_TX_MCI_GPM_BT_RXSS_THRES_QUERY", /* 150 */ + "COEX_BT_RXSS_THRES", /* 151 */ + "COEX_BT_PROFILE_ADD_RMV", /* 152 */ + "COEX_BT_SCHED_INFO", /* 153 */ + "COEX_TRF_MGMT", /* 154 */ + "COEX_SCHED_START", /* 155 */ + "COEX_SCHED_RESULT", /* 156 */ + "COEX_SCHED_ERROR", /* 157 */ + "COEX_SCHED_PRE_OP", /* 158 */ + "COEX_SCHED_POST_OP", /* 159 */ + "COEX_RX_RATE", /* 160 */ + "COEX_ACK_PRIORITY", /* 161 */ + "COEX_STATE_WLAN_VDEV_UP", /* 162 */ + "COEX_STATE_WLAN_VDEV_PEER_UPDATE", /* 163 */ + "COEX_STATE_WLAN_VDEV_STOP", /* 164 */ + "COEX_WLAN_PAUSE_PEER", /* 165 */ + "COEX_WLAN_UNPAUSE_PEER", /* 166 */ + "COEX_WLAN_PAUSE_INTERVAL_START", /* 167 */ + "COEX_WLAN_POSTPAUSE_INTERVAL_START", /* 168 */ + "COEX_TRF_FREERUN", /* 169 */ + "COEX_TRF_SHAPE_PM", /* 170 */ + "COEX_TRF_SHAPE_PSP", /* 171 */ + "COEX_TRF_SHAPE_S_CTS", /* 172 */ + "COEX_CHAIN_CONFIG", /* 173 */ + "COEX_SYSTEM_MONITOR", /* 174 */ + "COEX_SINGLECHAIN_INIT", /* 175 */ + "COEX_MULTICHAIN_INIT", /* 176 */ + "COEX_SINGLECHAIN_DBG_1", /* 177 */ + "COEX_SINGLECHAIN_DBG_2", /* 178 */ + "COEX_SINGLECHAIN_DBG_3", /* 179 */ + "COEX_MULTICHAIN_DBG_1", /* 180 */ + "COEX_MULTICHAIN_DBG_2", /* 181 */ + "COEX_MULTICHAIN_DBG_3", /* 182 */ + "COEX_PSP_TX_CB", /* 183 */ + "COEX_PSP_RX_CB", /* 184 */ + "COEX_PSP_STAT_1", /* 185 */ + "COEX_PSP_SPEC_POLL", /* 186 */ + "COEX_PSP_READY_STATE", /* 187 */ + "COEX_PSP_TX_STATUS_STATE", /* 188 */ + "COEX_PSP_RX_STATUS_STATE_1", /* 189 */ + "COEX_PSP_NOT_READY_STATE", /* 190 */ + "COEX_PSP_DISABLED_STATE", /* 191 */ + "COEX_PSP_ENABLED_STATE", /* 192 */ + "COEX_PSP_SEND_PSPOLL", /* 193 */ + "COEX_PSP_MGR_ENTER", /* 194 */ + "COEX_PSP_MGR_RESULT", /* 195 */ + "COEX_PSP_NONWLAN_INTERVAL", /* 196 */ + "COEX_PSP_STAT_2", /* 197 */ + "COEX_PSP_RX_STATUS_STATE_2", /* 198 */ + "COEX_PSP_ERROR", /* 199 */ + "COEX_T2BT", /* 200 */ + "COEX_BT_DURATION", /* 201 */ + "COEX_TX_MCI_GPM_WLAN_SCHED_INFO_TRIG", /* 202 */ + "COEX_TX_MCI_GPM_WLAN_SCHED_INFO_TRIG_RSP", /* 203 */ + "COEX_TX_MCI_GPM_SCAN_OP", /* 204 */ + "COEX_TX_MCI_GPM_BT_PAUSE_GPM_TX", /* 205 */ + "COEX_CTS2S_SEND", /* 206 */ + "COEX_CTS2S_RESULT", /* 207 */ + "COEX_ENTER_OCS", /* 208 */ + "COEX_EXIT_OCS", /* 209 */ + "COEX_UPDATE_OCS", /* 210 */ + "COEX_STATUS_OCS", /* 211 */ + "COEX_STATS_BT", /* 212 */ + "COEX_MWS_WLAN_INIT", + "COEX_MWS_WBTMR_SYNC", + "COEX_MWS_TYPE2_RX", + "COEX_MWS_TYPE2_TX", + "COEX_MWS_WLAN_CHAVD", + "COEX_MWS_WLAN_CHAVD_INSERT", + "COEX_MWS_WLAN_CHAVD_MERGE", + "COEX_MWS_WLAN_CHAVD_RPT", + "COEX_MWS_CP_MSG_SEND", + "COEX_MWS_CP_ESCAPE", + "COEX_MWS_CP_UNFRAME", + "COEX_MWS_CP_SYNC_UPDATE", + "COEX_MWS_CP_SYNC", + "COEX_MWS_CP_WLAN_STATE_IND", + "COEX_MWS_CP_SYNCRESP_TIMEOUT", + "COEX_MWS_SCHEME_UPDATE", + "COEX_MWS_WLAN_EVENT", + "COEX_MWS_UART_UNESCAPE", + "COEX_MWS_UART_ENCODE_SEND", + "COEX_MWS_UART_RECV_DECODE", + "COEX_MWS_UL_HDL", + "COEX_MWS_REMOTE_EVENT", + "COEX_MWS_OTHER", + "COEX_MWS_ERROR", + "COEX_MWS_ANT_DIVERSITY", /* 237 */ + "COEX_P2P_GO", + "COEX_P2P_CLIENT", + "COEX_SCC_1", + "COEX_SCC_2", + "COEX_MCC_1", + "COEX_MCC_2", + "COEX_TRF_SHAPE_NOA", + "COEX_NOA_ONESHOT", + "COEX_NOA_PERIODIC", + "COEX_LE_1", + "COEX_LE_2", + "COEX_ANT_1", + "COEX_ANT_2", + "COEX_ENTER_NOA", + "COEX_EXIT_NOA", + "COEX_BT_SCAN_PROTECT", /* 253 */ + "COEX_DEBUG_ID_END" /* 254 */ + }, + { + "ROAM_DBGID_DEFINITION_START", + "ROAM_MODULE_INIT", + "ROAM_DEV_START", + "ROAM_CONFIG_RSSI_THRESH", + "ROAM_CONFIG_SCAN_PERIOD", + "ROAM_CONFIG_AP_PROFILE", + "ROAM_CONFIG_CHAN_LIST", + "ROAM_CONFIG_SCAN_PARAMS", + "ROAM_CONFIG_RSSI_CHANGE", + "ROAM_SCAN_TIMER_START", + "ROAM_SCAN_TIMER_EXPIRE", + "ROAM_SCAN_TIMER_STOP", + "ROAM_SCAN_STARTED", + "ROAM_SCAN_COMPLETE", + "ROAM_SCAN_CANCELLED", + "ROAM_CANDIDATE_FOUND", + "ROAM_RSSI_ACTIVE_SCAN", + "ROAM_RSSI_ACTIVE_ROAM", + "ROAM_RSSI_GOOD", + "ROAM_BMISS_FIRST_RECV", + "ROAM_DEV_STOP", + "ROAM_FW_OFFLOAD_ENABLE", + "ROAM_CANDIDATE_SSID_MATCH", + "ROAM_CANDIDATE_SECURITY_MATCH", + "ROAM_LOW_RSSI_INTERRUPT", + "ROAM_HIGH_RSSI_INTERRUPT", + "ROAM_SCAN_REQUESTED", + "ROAM_BETTER_CANDIDATE_FOUND", + "ROAM_BETTER_AP_EVENT", + "ROAM_CANCEL_LOW_PRIO_SCAN", + "ROAM_FINAL_BMISS_RECVD", + "ROAM_CONFIG_SCAN_MODE", + "ROAM_BMISS_FINAL_SCAN_ENABLE", + "ROAM_SUITABLE_AP_EVENT", + "ROAM_RSN_IE_PARSE_ERROR", + "ROAM_WPA_IE_PARSE_ERROR", + "ROAM_SCAN_CMD_FROM_HOST", + "ROAM_HO_SORT_CANDIDATE", + "ROAM_HO_SAVE_CANDIDATE", + "ROAM_HO_GET_CANDIDATE", + "ROAM_HO_OFFLOAD_SET_PARAM", + "ROAM_HO_SM", + "ROAM_HO_HTT_SAVED", + "ROAM_HO_SYNC_START", + "ROAM_HO_START", + "ROAM_HO_COMPLETE", + "ROAM_HO_STOP", + "ROAM_HO_HTT_FORWARD", + "ROAM_DBGID_DEFINITION_END" + }, + { + "RESMGR_CHMGR_DEFINITION_START", + "RESMGR_CHMGR_PAUSE_COMPLETE", + "RESMGR_CHMGR_CHANNEL_CHANGE", + "RESMGR_CHMGR_RESUME_COMPLETE", + "RESMGR_CHMGR_VDEV_PAUSE", + "RESMGR_CHMGR_VDEV_UNPAUSE", + "RESMGR_CHMGR_CTS2S_TX_COMP", + "RESMGR_CHMGR_CFEND_TX_COMP", + "RESMGR_CHMGR_DEFINITION_END" + }, + { + "RESMGR_DEFINITION_START", + "RESMGR_OCS_ALLOCRAM_SIZE", + "RESMGR_OCS_RESOURCES", + "RESMGR_LINK_CREATE", + "RESMGR_LINK_DELETE", + "RESMGR_OCS_CHREQ_CREATE", + "RESMGR_OCS_CHREQ_DELETE", + "RESMGR_OCS_CHREQ_START", + "RESMGR_OCS_CHREQ_STOP", + "RESMGR_OCS_SCHEDULER_INVOKED", + "RESMGR_OCS_CHREQ_GRANT", + "RESMGR_OCS_CHREQ_COMPLETE", + "RESMGR_OCS_NEXT_TSFTIME", + "RESMGR_OCS_TSF_TIMEOUT_US", + "RESMGR_OCS_CURR_CAT_WINDOW", + "RESMGR_OCS_CURR_CAT_WINDOW_REQ", + "RESMGR_OCS_CURR_CAT_WINDOW_TIMESLOT", + "RESMGR_OCS_CHREQ_RESTART", + "RESMGR_OCS_CLEANUP_CH_ALLOCATORS", + "RESMGR_OCS_PURGE_CHREQ", + "RESMGR_OCS_CH_ALLOCATOR_FREE", + "RESMGR_OCS_RECOMPUTE_SCHEDULE", + "RESMGR_OCS_NEW_CAT_WINDOW_REQ", + "RESMGR_OCS_NEW_CAT_WINDOW_TIMESLOT", + "RESMGR_OCS_CUR_CH_ALLOC", + "RESMGR_OCS_WIN_CH_ALLOC", + "RESMGR_OCS_SCHED_CH_CHANGE", + "RESMGR_OCS_CONSTRUCT_CAT_WIN", + "RESMGR_OCS_CHREQ_PREEMPTED", + "RESMGR_OCS_CH_SWITCH_REQ", + "RESMGR_OCS_CHANNEL_SWITCHED", + "RESMGR_OCS_CLEANUP_STALE_REQS", + "RESMGR_OCS_CHREQ_UPDATE", + "RESMGR_OCS_REG_NOA_NOTIF", + "RESMGR_OCS_DEREG_NOA_NOTIF", + "RESMGR_OCS_GEN_PERIODIC_NOA", + "RESMGR_OCS_RECAL_QUOTAS", + "RESMGR_OCS_GRANTED_QUOTA_STATS", + "RESMGR_OCS_ALLOCATED_QUOTA_STATS", + "RESMGR_OCS_REQ_QUOTA_STATS", + "RESMGR_OCS_TRACKING_TIME_FIRED", + "RESMGR_VC_ARBITRATE_ATTRIBUTES", + "RESMGR_OCS_LATENCY_STRICT_TIME_SLOT", + "RESMGR_OCS_CURR_TSF", + "RESMGR_OCS_QUOTA_REM", + "RESMGR_OCS_LATENCY_CASE_NO", + "RESMGR_OCS_WIN_CAT_DUR", + "RESMGR_VC_UPDATE_CUR_VC", + "RESMGR_VC_REG_UNREG_LINK", + "RESMGR_VC_PRINT_LINK", + "RESMGR_OCS_MISS_TOLERANCE", + "RESMGR_DYN_SCH_ALLOCRAM_SIZE", + "RESMGR_DYN_SCH_ENABLE", + "RESMGR_DYN_SCH_ACTIVE", + "RESMGR_DYN_SCH_CH_STATS_START", + "RESMGR_DYN_SCH_CH_SX_STATS", + "RESMGR_DYN_SCH_TOT_UTIL_PER", + "RESMGR_DYN_SCH_HOME_CH_QUOTA", + "RESMGR_OCS_REG_RECAL_QUOTA_NOTIF", + "RESMGR_OCS_DEREG_RECAL_QUOTA_NOTIF", + "RESMGR_DEFINITION_END" + }, + { + "VDEV_MGR_DEBID_DEFINITION_START", /* vdev Mgr */ + "VDEV_MGR_FIRST_BEACON_MISS_DETECTED", + "VDEV_MGR_FINAL_BEACON_MISS_DETECTED", + "VDEV_MGR_BEACON_IN_SYNC", + "VDEV_MGR_AP_KEEPALIVE_IDLE", + "VDEV_MGR_AP_KEEPALIVE_INACTIVE", + "VDEV_MGR_AP_KEEPALIVE_UNRESPONSIVE", + "VDEV_MGR_AP_TBTT_CONFIG", + "VDEV_MGR_FIRST_BCN_RECEIVED", + "VDEV_MGR_VDEV_START", + "VDEV_MGR_VDEV_UP", + "VDEV_MGR_PEER_AUTHORIZED", + "VDEV_MGR_OCS_HP_LP_REQ_POSTED", + "VDEV_MGR_VDEV_START_OCS_HP_REQ_COMPLETE", + "VDEV_MGR_VDEV_START_OCS_HP_REQ_STOP", + "VDEV_MGR_HP_START_TIME", + "VDEV_MGR_VDEV_PAUSE_DELAY_UPDATE", + "VDEV_MGR_VDEV_PAUSE_FAIL", + "VDEV_MGR_GEN_PERIODIC_NOA", + "VDEV_MGR_OFF_CHAN_GO_CH_REQ_SETUP", + "VDEV_MGR_DEFINITION_END", + }, + { + "SCAN_START_COMMAND_FAILED", /* scan */ + "SCAN_STOP_COMMAND_FAILED", + "SCAN_EVENT_SEND_FAILED", + "SCAN_ENGINE_START", + "SCAN_ENGINE_CANCEL_COMMAND", + "SCAN_ENGINE_STOP_DUE_TO_TIMEOUT", + "SCAN_EVENT_SEND_TO_HOST", + "SCAN_FWLOG_EVENT_ADD", + "SCAN_FWLOG_EVENT_REM", + "SCAN_FWLOG_EVENT_PREEMPTED", + "SCAN_FWLOG_EVENT_RESTARTED", + "SCAN_FWLOG_EVENT_COMPLETED", + }, + { + "RATECTRL_DBGID_DEFINITION_START", /* Rate ctrl */ + "RATECTRL_DBGID_ASSOC", + "RATECTRL_DBGID_NSS_CHANGE", + "RATECTRL_DBGID_CHAINMASK_ERR", + "RATECTRL_DBGID_UNEXPECTED_FRAME", + "RATECTRL_DBGID_WAL_RCQUERY", + "RATECTRL_DBGID_WAL_RCUPDATE", + "RATECTRL_DBGID_GTX_UPDATE", + "RATECTRL_DBGID_DEFINITION_END" + }, + { + "AP_PS_DBGID_DEFINITION_START", + "AP_PS_DBGID_UPDATE_TIM", + "AP_PS_DBGID_PEER_STATE_CHANGE", + "AP_PS_DBGID_PSPOLL", + "AP_PS_DBGID_PEER_CREATE", + "AP_PS_DBGID_PEER_DELETE", + "AP_PS_DBGID_VDEV_CREATE", + "AP_PS_DBGID_VDEV_DELETE", + "AP_PS_DBGID_SYNC_TIM", + "AP_PS_DBGID_NEXT_RESPONSE", + "AP_PS_DBGID_START_SP", + "AP_PS_DBGID_COMPLETED_EOSP", + "AP_PS_DBGID_TRIGGER", + "AP_PS_DBGID_DUPLICATE_TRIGGER", + "AP_PS_DBGID_UAPSD_RESPONSE", + "AP_PS_DBGID_SEND_COMPLETE", + "AP_PS_DBGID_SEND_N_COMPLETE", + "AP_PS_DBGID_DETECT_OUT_OF_SYNC_STA", + "AP_PS_DBGID_DELIVER_CAB", + }, + { + "" /* Block Ack */ + }, + /* Mgmt TxRx */ + { + "MGMT_TXRX_DBGID_DEFINITION_START", + "MGMT_TXRX_FORWARD_TO_HOST", + "MGMT_TXRX_DBGID_DEFINITION_END", + }, + { /* Data TxRx */ + "DATA_TXRX_DBGID_DEFINITION_START", + "DATA_TXRX_DBGID_RX_DATA_SEQ_LEN_INFO", + "DATA_TXRX_DBGID_DEFINITION_END", + }, + {"" /* HTT */ + }, + {"" /* HOST */ + }, + {"" /* BEACON */ + "BEACON_EVENT_SWBA_SEND_FAILED", + "BEACON_EVENT_EARLY_RX_BMISS_STATUS", + "BEACON_EVENT_EARLY_RX_SLEEP_SLOP", + "BEACON_EVENT_EARLY_RX_CONT_BMISS_TIMEOUT", + "BEACON_EVENT_EARLY_RX_PAUSE_SKIP_BCN_NUM", + "BEACON_EVENT_EARLY_RX_CLK_DRIFT", + "BEACON_EVENT_EARLY_RX_AP_DRIFT", + "BEACON_EVENT_EARLY_RX_BCN_TYPE",}, + { /* Offload Mgr */ + "OFFLOAD_MGR_DBGID_DEFINITION_START", + "OFFLOADMGR_REGISTER_OFFLOAD", + "OFFLOADMGR_DEREGISTER_OFFLOAD", + "OFFLOADMGR_NO_REG_DATA_HANDLERS", + "OFFLOADMGR_NO_REG_EVENT_HANDLERS", + "OFFLOADMGR_REG_OFFLOAD_FAILED", + "OFFLOADMGR_DBGID_DEFINITION_END", + }, + { + "WAL_DBGID_DEFINITION_START", + "WAL_DBGID_FAST_WAKE_REQUEST", + "WAL_DBGID_FAST_WAKE_RELEASE", + "WAL_DBGID_SET_POWER_STATE", + "WAL_DBGID_MISSING", + "WAL_DBGID_CHANNEL_CHANGE_FORCE_RESET", + "WAL_DBGID_CHANNEL_CHANGE", + "WAL_DBGID_VDEV_START", + "WAL_DBGID_VDEV_STOP", + "WAL_DBGID_VDEV_UP", + "WAL_DBGID_VDEV_DOWN", + "WAL_DBGID_SW_WDOG_RESET", + "WAL_DBGID_TX_SCH_REGISTER_TIDQ", + "WAL_DBGID_TX_SCH_UNREGISTER_TIDQ", + "WAL_DBGID_TX_SCH_TICKLE_TIDQ", + "WAL_DBGID_XCESS_FAILURES", + "WAL_DBGID_AST_ADD_WDS_ENTRY", + "WAL_DBGID_AST_DEL_WDS_ENTRY", + "WAL_DBGID_AST_WDS_ENTRY_PEER_CHG", + "WAL_DBGID_AST_WDS_SRC_LEARN_FAIL", + "WAL_DBGID_STA_KICKOUT", + "WAL_DBGID_BAR_TX_FAIL", + "WAL_DBGID_BAR_ALLOC_FAIL", + "WAL_DBGID_LOCAL_DATA_TX_FAIL", + "WAL_DBGID_SECURITY_PM4_QUEUED", + "WAL_DBGID_SECURITY_GM1_QUEUED", + "WAL_DBGID_SECURITY_PM4_SENT", + "WAL_DBGID_SECURITY_ALLOW_DATA", + "WAL_DBGID_SECURITY_UCAST_KEY_SET", + "WAL_DBGID_SECURITY_MCAST_KEY_SET", + "WAL_DBGID_SECURITY_ENCR_EN", + "WAL_DBGID_BB_WDOG_TRIGGERED", + "WAL_DBGID_RX_LOCAL_BUFS_LWM", + "WAL_DBGID_RX_LOCAL_DROP_LARGE_MGMT", + "WAL_DBGID_VHT_ILLEGAL_RATE_PHY_ERR_DETECTED", + "WAL_DBGID_DEV_RESET", + "WAL_DBGID_TX_BA_SETUP", + "WAL_DBGID_RX_BA_SETUP", + "WAL_DBGID_DEV_TX_TIMEOUT", + "WAL_DBGID_DEV_RX_TIMEOUT", + "WAL_DBGID_STA_VDEV_XRETRY", + "WAL_DBGID_DCS", + "WAL_DBGID_MGMT_TX_FAIL", + "WAL_DBGID_SET_M4_SENT_MANUALLY", + "WAL_DBGID_PROCESS_4_WAY_HANDSHAKE", + "WAL_DBGID_WAL_CHANNEL_CHANGE_START", + "WAL_DBGID_WAL_CHANNEL_CHANGE_COMPLETE", + "WAL_DBGID_WHAL_CHANNEL_CHANGE_START", + "WAL_DBGID_WHAL_CHANNEL_CHANGE_COMPLETE", + "WAL_DBGID_TX_MGMT_DESCID_SEQ_TYPE_LEN", + "WAL_DBGID_TX_DATA_MSDUID_SEQ_TYPE_LEN", + "WAL_DBGID_TX_DISCARD", + "WAL_DBGID_TX_MGMT_COMP_DESCID_STATUS", + "WAL_DBGID_TX_DATA_COMP_MSDUID_STATUS", + "WAL_DBGID_RESET_PCU_CYCLE_CNT", + "WAL_DBGID_SETUP_RSSI_INTERRUPTS", + "WAL_DBGID_BRSSI_CONFIG", + "WAL_DBGID_CURRENT_BRSSI_AVE", + "WAL_DBGID_BCN_TX_COMP", + "WAL_DBGID_SET_HW_CHAINMASK", + "WAL_DBGID_SET_HW_CHAINMASK_TXRX_STOP_FAIL", + "WAL_DBGID_GET_HW_CHAINMASK", + "WAL_DBGID_SMPS_DISABLE", + "WAL_DBGID_SMPS_ENABLE_HW_CNTRL", + "WAL_DBGID_SMPS_SWSEL_CHAINMASK", + "WAL_DBGID_DEFINITION_END", + }, + { + "" /* DE */ + }, + { + "" /* pcie lp */ + }, + { + /* RTT */ + "RTT_CALL_FLOW", + "RTT_REQ_SUB_TYPE", + "RTT_MEAS_REQ_HEAD", + "RTT_MEAS_REQ_BODY", + "", + "", + "RTT_INIT_GLOBAL_STATE", + "", + "RTT_REPORT", + "", + "RTT_ERROR_REPORT", + "RTT_TIMER_STOP", + "RTT_SEND_TM_FRAME", + "RTT_V3_RESP_CNT", + "RTT_V3_RESP_FINISH", + "RTT_CHANNEL_SWITCH_REQ", + "RTT_CHANNEL_SWITCH_GRANT", + "RTT_CHANNEL_SWITCH_COMPLETE", + "RTT_CHANNEL_SWITCH_PREEMPT", + "RTT_CHANNEL_SWITCH_STOP", + "RTT_TIMER_START", + }, + { /* RESOURCE */ + "RESOURCE_DBGID_DEFINITION_START", + "RESOURCE_PEER_ALLOC", + "RESOURCE_PEER_FREE", + "RESOURCE_PEER_ALLOC_WAL_PEER", + "RESOURCE_PEER_NBRHOOD_MGMT_ALLOC", + "RESOURCE_PEER_NBRHOOD_MGMT_INFO," "RESOURCE_DBGID_DEFINITION_END", + }, + { /* DCS */ + "WLAN_DCS_DBGID_INIT", + "WLAN_DCS_DBGID_WMI_CWINT", + "WLAN_DCS_DBGID_TIMER", + "WLAN_DCS_DBGID_CMDG", + "WLAN_DCS_DBGID_CMDS", + "WLAN_DCS_DBGID_DINIT" + }, + { /* CACHEMGR */ + "" + }, + { /* ANI */ + "ANI_DBGID_POLL", + "ANI_DBGID_CONTROL", + "ANI_DBGID_OFDM_PARAMS", + "ANI_DBGID_CCK_PARAMS", + "ANI_DBGID_RESET", + "ANI_DBGID_RESTART", + "ANI_DBGID_OFDM_LEVEL", + "ANI_DBGID_CCK_LEVEL", + "ANI_DBGID_FIRSTEP", + "ANI_DBGID_CYCPWR", + "ANI_DBGID_MRC_CCK", + "ANI_DBGID_SELF_CORR_LOW", + "ANI_DBGID_ENABLE", + "ANI_DBGID_CURRENT_LEVEL", + "ANI_DBGID_POLL_PERIOD", + "ANI_DBGID_LISTEN_PERIOD", + "ANI_DBGID_OFDM_LEVEL_CFG", + "ANI_DBGID_CCK_LEVEL_CFG" + }, + { + "P2P_DBGID_DEFINITION_START", + "P2P_DEV_REGISTER", + "P2P_HANDLE_NOA", + "P2P_UPDATE_SCHEDULE_OPPS", + "P2P_UPDATE_SCHEDULE", + "P2P_UPDATE_START_TIME", + "P2P_UPDATE_START_TIME_DIFF_TSF32", + "P2P_UPDATE_START_TIME_FINAL", + "P2P_SETUP_SCHEDULE_TIMER", + "P2P_PROCESS_SCHEDULE_AFTER_CALC", + "P2P_PROCESS_SCHEDULE_STARTED_TIMER", + "P2P_CALC_SCHEDULES_FIRST_CALL_ALL_NEXT_EVENT", + "P2P_CALC_SCHEDULES_FIRST_VALUE", + "P2P_CALC_SCHEDULES_EARLIEST_NEXT_EVENT", + "P2P_CALC_SCHEDULES_SANITY_COUNT", + "P2P_CALC_SCHEDULES_CALL_ALL_NEXT_EVENT_FROM_WHILE_LOOP", + "P2P_CALC_SCHEDULES_TIMEOUT_1", + "P2P_CALC_SCHEDULES_TIMEOUT_2", + "P2P_FIND_ALL_NEXT_EVENTS_REQ_EXPIRED", + "P2P_FIND_ALL_NEXT_EVENTS_REQ_ACTIVE", + "P2P_FIND_NEXT_EVENT_REQ_NOT_STARTED", + "P2P_FIND_NEXT_EVENT_REQ_COMPLETE_NON_PERIODIC", + "P2P_FIND_NEXT_EVENT_IN_MID_OF_NOA", + "P2P_FIND_NEXT_EVENT_REQ_COMPLETE", + "P2P_SCHEDULE_TIMEOUT", + "P2P_CALC_SCHEDULES_ENTER", + "P2P_PROCESS_SCHEDULE_ENTER", + "P2P_FIND_ALL_NEXT_EVENTS_INDIVIDUAL_REQ_AFTER_CHANGE", + "P2P_FIND_ALL_NEXT_EVENTS_INDIVIDUAL_REQ_BEFORE_CHANGE", + "P2P_FIND_ALL_NEXT_EVENTS_ENTER", + "P2P_FIND_NEXT_EVENT_ENTER", + "P2P_NOA_GO_PRESENT", + "P2P_NOA_GO_ABSENT", + "P2P_GO_NOA_NOTIF", + "P2P_GO_TBTT_OFFSET", + "P2P_GO_GET_NOA_INFO", + "P2P_GO_ADD_ONE_SHOT_NOA", + "P2P_GO_GET_NOA_IE", + "P2P_GO_BCN_TX_COMP", + "P2P_DBGID_DEFINITION_END", + }, + { + "CSA_DBGID_DEFINITION_START", + "CSA_OFFLOAD_POOL_INIT", + "CSA_OFFLOAD_REGISTER_VDEV", + "CSA_OFFLOAD_DEREGISTER_VDEV", + "CSA_DEREGISTER_VDEV_ERROR", + "CSA_OFFLOAD_BEACON_RECEIVED", + "CSA_OFFLOAD_BEACON_CSA_RECV", + "CSA_OFFLOAD_CSA_RECV_ERROR_IE", + "CSA_OFFLOAD_CSA_TIMER_ERROR", + "CSA_OFFLOAD_CSA_TIMER_EXP", + "CSA_OFFLOAD_WMI_EVENT_ERROR", + "CSA_OFFLOAD_WMI_EVENT_SENT", + "CSA_OFFLOAD_WMI_CHANSWITCH_RECV", + "CSA_DBGID_DEFINITION_END", + }, + { /* NLO offload */ + "" + }, + { + "WLAN_CHATTER_DBGID_DEFINITION_START", + "WLAN_CHATTER_ENTER", + "WLAN_CHATTER_EXIT", + "WLAN_CHATTER_FILTER_HIT", + "WLAN_CHATTER_FILTER_MISS", + "WLAN_CHATTER_FILTER_FULL", + "WLAN_CHATTER_FILTER_TM_ADJ", + "WLAN_CHATTER_BUFFER_FULL", + "WLAN_CHATTER_TIMEOUT", + "WLAN_CHATTER_DBGID_DEFINITION_END", + }, + { + "WOW_DBGID_DEFINITION_START", + "WOW_ENABLE_CMDID", + "WOW_RECV_DATA_PKT", + "WOW_WAKE_HOST_DATA", + "WOW_RECV_MGMT", + "WOW_WAKE_HOST_MGMT", + "WOW_RECV_EVENT", + "WOW_WAKE_HOST_EVENT", + "WOW_INIT", + "WOW_RECV_MAGIC_PKT", + "WOW_RECV_BITMAP_PATTERN", + "WOW_AP_VDEV_DISALLOW", + "WOW_STA_VDEV_DISALLOW", + "WOW_P2PGO_VDEV_DISALLOW", + "WOW_NS_OFLD_ENABLE", + "WOW_ARP_OFLD_ENABLE", + "WOW_NS_ARP_OFLD_DISABLE", + "WOW_NS_RECEIVED", + "WOW_NS_REPLIED", + "WOW_ARP_RECEIVED", + "WOW_ARP_REPLIED", + "WOW_DBGID_DEFINITION_END", + }, + { /* WAL VDEV */ + "" + }, + { /* WAL PDEV */ + "" + }, + { /* TEST */ + "TP_CHANGE_CHANNEL", + "TP_LOCAL_SEND", + }, + { /* STA SMPS */ + "STA_SMPS_DBGID_DEFINITION_START", + "STA_SMPS_DBGID_CREATE_PDEV_INSTANCE", + "STA_SMPS_DBGID_CREATE_VIRTUAL_CHAN_INSTANCE", + "STA_SMPS_DBGID_DELETE_VIRTUAL_CHAN_INSTANCE", + "STA_SMPS_DBGID_CREATE_STA_INSTANCE", + "STA_SMPS_DBGID_DELETE_STA_INSTANCE", + "STA_SMPS_DBGID_VIRTUAL_CHAN_SMPS_START", + "STA_SMPS_DBGID_VIRTUAL_CHAN_SMPS_STOP", + "STA_SMPS_DBGID_SEND_SMPS_ACTION_FRAME", + "STA_SMPS_DBGID_HOST_FORCED_MODE", + "STA_SMPS_DBGID_FW_FORCED_MODE", + "STA_SMPS_DBGID_RSSI_THRESHOLD_CROSSED", + "STA_SMPS_DBGID_SMPS_ACTION_FRAME_COMPLETION", + "STA_SMPS_DBGID_DTIM_EBT_EVENT_CHMASK_UPDATE", + "STA_SMPS_DBGID_DTIM_CHMASK_UPDATE", + "STA_SMPS_DBGID_DTIM_BEACON_EVENT_CHMASK_UPDATE", + "STA_SMPS_DBGID_DTIM_POWER_STATE_CHANGE", + "STA_SMPS_DBGID_DTIM_CHMASK_UPDATE_SLEEP", + "STA_SMPS_DBGID_DTIM_CHMASK_UPDATE_AWAKE", + "SMPS_DBGID_DEFINITION_END", + }, + { /* SWBMISS */ + "SWBMISS_DBGID_DEFINITION_START", + "SWBMISS_ENABLED", + "SWBMISS_DISABLED", + "SWBMISS_DBGID_DEFINITION_END", + }, + { /* WMMAC */ + "" + }, + { /* TDLS */ + "TDLS_DBGID_DEFINITION_START", + "TDLS_DBGID_VDEV_CREATE", + "TDLS_DBGID_VDEV_DELETE", + "TDLS_DBGID_ENABLED_PASSIVE", + "TDLS_DBGID_ENABLED_ACTIVE", + "TDLS_DBGID_DISABLED", + "TDLS_DBGID_CONNTRACK_TIMER", + "TDLS_DBGID_WAL_SET", + "TDLS_DBGID_WAL_GET", + "TDLS_DBGID_WAL_PEER_UPDATE_SET", + "TDLS_DBGID_WAL_PEER_UPDATE_EVT", + "TDLS_DBGID_WAL_VDEV_CREATE", + "TDLS_DBGID_WAL_VDEV_DELETE", + "TDLS_DBGID_WLAN_EVENT", + "TDLS_DBGID_WLAN_PEER_UPDATE_SET", + "TDLS_DBGID_PEER_EVT_DRP_THRESH", + "TDLS_DBGID_PEER_EVT_DRP_RATE", + "TDLS_DBGID_PEER_EVT_DRP_RSSI", + "TDLS_DBGID_PEER_EVT_DISCOVER", + "TDLS_DBGID_PEER_EVT_DELETE", + "TDLS_DBGID_PEER_CAP_UPDATE", + "TDLS_DBGID_UAPSD_SEND_PTI_FRAME", + "TDLS_DBGID_UAPSD_SEND_PTI_FRAME2PEER", + "TDLS_DBGID_UAPSD_START_PTR_TIMER", + "TDLS_DBGID_UAPSD_CANCEL_PTR_TIMER", + "TDLS_DBGID_UAPSD_PTR_TIMER_TIMEOUT", + "TDLS_DBGID_UAPSD_STA_PS_EVENT_HANDLER", + "TDLS_DBGID_UAPSD_PEER_EVENT_HANDLER", + "TDLS_DBGID_UAPSD_PS_DEFAULT_SETTINGS", + "TDLS_DBGID_UAPSD_GENERIC", + }, + { /* HB */ + "WLAN_HB_DBGID_DEFINITION_START", + "WLAN_HB_DBGID_INIT", + "WLAN_HB_DBGID_TCP_GET_TXBUF_FAIL", + "WLAN_HB_DBGID_TCP_SEND_FAIL", + "WLAN_HB_DBGID_BSS_PEER_NULL", + "WLAN_HB_DBGID_UDP_GET_TXBUF_FAIL", + "WLAN_HB_DBGID_UDP_SEND_FAIL", + "WLAN_HB_DBGID_WMI_CMD_INVALID_PARAM", + "WLAN_HB_DBGID_WMI_CMD_INVALID_OP", + "WLAN_HB_DBGID_WOW_NOT_ENTERED", + "WLAN_HB_DBGID_ALLOC_SESS_FAIL", + "WLAN_HB_DBGID_CTX_NULL", + "WLAN_HB_DBGID_CHKSUM_ERR", + "WLAN_HB_DBGID_UDP_TX", + "WLAN_HB_DBGID_TCP_TX", + "WLAN_HB_DBGID_DEFINITION_END", + }, + { /* TXBF */ + "TXBFEE_DBGID_START", + "TXBFEE_DBGID_NDPA_RECEIVED", + "TXBFEE_DBGID_HOST_CONFIG_TXBFEE_TYPE", + "TXBFER_DBGID_SEND_NDPA", + "TXBFER_DBGID_GET_NDPA_BUF_FAIL", + "TXBFER_DBGID_SEND_NDPA_FAIL", + "TXBFER_DBGID_GET_NDP_BUF_FAIL", + "TXBFER_DBGID_SEND_NDP_FAIL", + "TXBFER_DBGID_GET_BRPOLL_BUF_FAIL", + "TXBFER_DBGID_SEND_BRPOLL_FAIL", + "TXBFER_DBGID_HOST_CONFIG_CMDID", + "TXBFEE_DBGID_HOST_CONFIG_CMDID", + "TXBFEE_DBGID_ENABLED_ENABLED_UPLOAD_H", + "TXBFEE_DBGID_UPLOADH_CV_TAG", + "TXBFEE_DBGID_UPLOADH_H_TAG", + "TXBFEE_DBGID_CAPTUREH_RECEIVED", + "TXBFEE_DBGID_PACKET_IS_STEERED", + "TXBFEE_UPLOADH_EVENT_ALLOC_MEM_FAIL", + "TXBFEE_DBGID_END", + }, + { /*BATCH SCAN */ + }, + { /*THERMAL MGR */ + "THERMAL_MGR_DBGID_DEFINITION_START", + "THERMAL_MGR_NEW_THRESH", + "THERMAL_MGR_THRESH_CROSSED", + "THERMAL_MGR_DBGID_DEFINITION END", + }, + { /* WLAN_MODULE_PHYERR_DFS */ + "" + }, + { + /* WLAN_MODULE_RMC */ + "RMC_DBGID_DEFINITION_START", + "RMC_CREATE_INSTANCE", + "RMC_DELETE_INSTANCE", + "RMC_LDR_SEL", + "RMC_NO_LDR", + "RMC_LDR_NOT_SEL", + "RMC_LDR_INF_SENT", + "RMC_PEER_ADD", + "RMC_PEER_DELETE", + "RMC_PEER_UNKNOWN", + "RMC_SET_MODE", + "RMC_SET_ACTION_PERIOD", + "RMC_ACRION_FRAME_RX", + "RMC_DBGID_DEFINITION_END", + }, + { + /* WLAN_MODULE_STATS */ + "WLAN_STATS_DBGID_DEFINITION_START", + "WLAN_STATS_DBGID_EST_LINKSPEED_VDEV_EN_DIS", + "WLAN_STATS_DBGID_EST_LINKSPEED_CHAN_TIME_START", + "WLAN_STATS_DBGID_EST_LINKSPEED_CHAN_TIME_END", + "WLAN_STATS_DBGID_EST_LINKSPEED_CALC", + "WLAN_STATS_DBGID_EST_LINKSPEED_UPDATE_HOME_CHAN", + "WLAN_STATS_DBGID_DEFINITION_END", + }, + { + /* WLAN_MODULE_NAN */ + }, + { + /* WLAN_MODULE_IBSS_PWRSAVE */ + "IBSS_PS_DBGID_DEFINITION_START", + "IBSS_PS_DBGID_PEER_CREATE", + "IBSS_PS_DBGID_PEER_DELETE", + "IBSS_PS_DBGID_VDEV_CREATE", + "IBSS_PS_DBGID_VDEV_DELETE", + "IBSS_PS_DBGID_VDEV_EVENT", + "IBSS_PS_DBGID_PEER_EVENT", + "IBSS_PS_DBGID_DELIVER_CAB", + "IBSS_PS_DBGID_DELIVER_UC_DATA", + "IBSS_PS_DBGID_DELIVER_UC_DATA_ERROR", + "IBSS_PS_DBGID_UC_INACTIVITY_TMR_RESTART", + "IBSS_PS_DBGID_MC_INACTIVITY_TMR_RESTART", + "IBSS_PS_DBGID_NULL_TX_COMPLETION", + "IBSS_PS_DBGID_ATIM_TIMER_START", + "IBSS_PS_DBGID_UC_ATIM_SEND", + "IBSS_PS_DBGID_BC_ATIM_SEND", + "IBSS_PS_DBGID_UC_TIMEOUT", + "IBSS_PS_DBGID_PWR_COLLAPSE_ALLOWED", + "IBSS_PS_DBGID_PWR_COLLAPSE_NOT_ALLOWED", + "IBSS_PS_DBGID_SET_PARAM", + "IBSS_PS_DBGID_HOST_TX_PAUSE", + "IBSS_PS_DBGID_HOST_TX_UNPAUSE", + "IBSS_PS_DBGID_PS_DESC_BIN_HWM", + "IBSS_PS_DBGID_PS_DESC_BIN_LWM", + "IBSS_PS_DBGID_PS_KICKOUT_PEER", + "IBSS_PS_DBGID_SET_PEER_PARAM", + "IBSS_PS_DBGID_BCN_ATIM_WIN_MISMATCH", + "IBSS_PS_DBGID_RX_CHAINMASK_CHANGE", + }, + { + /* HIF UART Interface DBGIDs */ + "HIF_UART_DBGID_START", + "HIF_UART_DBGID_POWER_STATE", + "HIF_UART_DBGID_TXRX_FLOW", + "HIF_UART_DBGID_TXRX_CTRL_CHAR", + "HIF_UART_DBGID_TXRX_BUF_DUMP", + }, + { + /* LPI */ + "" + }, + { + /* EXTSCAN DBGIDs */ + "EXTSCAN_START", + "EXTSCAN_STOP", + "EXTSCAN_CLEAR_ENTRY_CONTENT", + "EXTSCAN_GET_FREE_ENTRY_SUCCESS", + "EXTSCAN_GET_FREE_ENTRY_INCONSISTENT", + "EXTSCAN_GET_FREE_ENTRY_NO_MORE_ENTRIES", + "EXTSCAN_CREATE_ENTRY_SUCCESS", + "EXTSCAN_CREATE_ENTRY_ERROR", + "EXTSCAN_SEARCH_SCAN_ENTRY_QUEUE", + "EXTSCAN_SEARCH_SCAN_ENTRY_KEY_FOUND", + "EXTSCAN_SEARCH_SCAN_ENTRY_KEY_NOT_FOUND", + "EXTSCAN_ADD_ENTRY", + "EXTSCAN_BUCKET_SEND_OPERATION_EVENT", + "EXTSCAN_BUCKET_SEND_OPERATION_EVENT_FAILED", + "EXTSCAN_BUCKET_START_SCAN_CYCLE", + "EXTSCAN_BUCKET_PERIODIC_TIMER", + "EXTSCAN_SEND_START_STOP_EVENT", + "EXTSCAN_NOTIFY_WLAN_CHANGE", + "EXTSCAN_NOTIFY_WLAN_HOTLIST_MATCH", + "EXTSCAN_MAIN_RECEIVED_FRAME", + "EXTSCAN_MAIN_NO_SSID_IE", + "EXTSCAN_MAIN_MALFORMED_FRAME", + "EXTSCAN_FIND_BSSID_BY_REFERENCE", + "EXTSCAN_FIND_BSSID_BY_REFERENCE_ERROR", + "EXTSCAN_NOTIFY_TABLE_USAGE", + "EXTSCAN_FOUND_RSSI_ENTRY", + "EXTSCAN_BSSID_FOUND_RSSI_SAMPLE", + "EXTSCAN_BSSID_ADDED_RSSI_SAMPLE", + "EXTSCAN_BSSID_REPLACED_RSSI_SAMPLE", + "EXTSCAN_BSSID_TRANSFER_CURRENT_SAMPLES", + "EXTSCAN_BUCKET_PROCESS_SCAN_EVENT", + "EXTSCAN_BUCKET_CANNOT_FIND_BUCKET", + "EXTSCAN_START_SCAN_REQUEST_FAILED", + "EXTSCAN_BUCKET_STOP_CURRENT_SCANS", + "EXTSCAN_BUCKET_SCAN_STOP_REQUEST", + "EXTSCAN_BUCKET_PERIODIC_TIMER_ERROR", + "EXTSCAN_BUCKET_START_OPERATION", + "EXTSCAN_START_INTERNAL_ERROR", + "EXTSCAN_NOTIFY_HOTLIST_MATCH", + "EXTSCAN_CONFIG_HOTLIST_TABLE", + "EXTSCAN_CONFIG_WLAN_CHANGE_TABLE", + }, + { /* UNIT_TEST */ + "UNIT_TEST_GEN", + }, + { /* MLME */ + "MLME_DEBUG_CMN", + "MLME_IF", + "MLME_AUTH", + "MLME_REASSOC", + "MLME_DEAUTH", + "MLME_DISASSOC", + "MLME_ROAM", + "MLME_RETRY", + "MLME_TIMER", + "MLME_FRMPARSE", + }, + { /*SUPPLICANT */ + "SUPPL_INIT", + "SUPPL_RECV_EAPOL", + "SUPPL_RECV_EAPOL_TIMEOUT", + "SUPPL_SEND_EAPOL", + "SUPPL_MIC_MISMATCH", + "SUPPL_FINISH", + }, +}; + +int dbglog_module_log_enable(wmi_unified_t wmi_handle, A_UINT32 mod_id, + bool isenable) +{ + A_UINT32 val = 0; + + if (mod_id > WLAN_MODULE_ID_MAX) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("dbglog_module_log_enable: Invalid module id %d\n", + mod_id)); + return -EINVAL; + } + + WMI_DBGLOG_SET_MODULE_ID(val, mod_id); + if (isenable) { + /* set it to global module level */ + WMI_DBGLOG_SET_LOG_LEVEL(val, DBGLOG_INFO); + } else { + /* set it to ERROR level */ + WMI_DBGLOG_SET_LOG_LEVEL(val, DBGLOG_ERR); + } + wma_config_debug_module_cmd(wmi_handle, WMI_DEBUG_LOG_PARAM_LOG_LEVEL, + val, NULL, 0); + + return 0; +} + +int dbglog_vap_log_enable(wmi_unified_t wmi_handle, A_UINT16 vap_id, + bool isenable) +{ + if (vap_id > DBGLOG_MAX_VDEVID) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("dbglog_vap_log_enable:Invalid vap_id %d\n", + vap_id)); + return -EINVAL; + } + + wma_config_debug_module_cmd(wmi_handle, + isenable ? WMI_DEBUG_LOG_PARAM_VDEV_ENABLE : + WMI_DEBUG_LOG_PARAM_VDEV_DISABLE, vap_id, + NULL, 0); + + return 0; +} + +int dbglog_set_log_lvl(wmi_unified_t wmi_handle, enum DBGLOG_LOG_LVL log_lvl) +{ + A_UINT32 val = 0; + + if (log_lvl > DBGLOG_LVL_MAX) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("dbglog_set_log_lvl:Invalid log level %d\n", + log_lvl)); + return -EINVAL; + } + + WMI_DBGLOG_SET_MODULE_ID(val, WMI_DEBUG_LOG_MODULE_ALL); + WMI_DBGLOG_SET_LOG_LEVEL(val, log_lvl); + wma_config_debug_module_cmd(wmi_handle, WMI_DEBUG_LOG_PARAM_LOG_LEVEL, + val, NULL, 0); + + return 0; +} + +int dbglog_set_mod_log_lvl(wmi_unified_t wmi_handle, A_UINT32 mod_log_lvl) +{ + A_UINT32 val = 0; + /* set the global module level to log_lvl */ + WMI_DBGLOG_SET_MODULE_ID(val, (mod_log_lvl / 10)); + WMI_DBGLOG_SET_LOG_LEVEL(val, (mod_log_lvl % 10)); + wma_config_debug_module_cmd(wmi_handle, WMI_DEBUG_LOG_PARAM_LOG_LEVEL, + val, NULL, 0); + + return 0; +} + +void +dbglog_set_vap_enable_bitmap(wmi_unified_t wmi_handle, + A_UINT32 vap_enable_bitmap) +{ + wma_config_debug_module_cmd(wmi_handle, + WMI_DEBUG_LOG_PARAM_VDEV_ENABLE_BITMAP, + vap_enable_bitmap, NULL, 0); +} + +void +dbglog_set_mod_enable_bitmap(wmi_unified_t wmi_handle, A_UINT32 log_level, + A_UINT32 *mod_enable_bitmap, A_UINT32 bitmap_len) +{ + wma_config_debug_module_cmd(wmi_handle, + WMI_DEBUG_LOG_PARAM_MOD_ENABLE_BITMAP, + log_level, mod_enable_bitmap, bitmap_len); +} + +int dbglog_report_enable(wmi_unified_t wmi_handle, bool isenable) +{ + int bitmap[2] = { 0 }; + + if (isenable > true) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("dbglog_report_enable:Invalid value %d\n", + isenable)); + return -EINVAL; + } + + if (isenable) { + /* set the vap enable bitmap */ + dbglog_set_vap_enable_bitmap(wmi_handle, 0xFFFF); + bitmap[0] = 0xFFFFFFFF; + bitmap[1] = 0x1F; + /* set the module level bitmap */ + dbglog_set_mod_enable_bitmap(wmi_handle, 0x0, bitmap, 2); + } else { + dbglog_set_vap_enable_bitmap(wmi_handle, bitmap[0]); + dbglog_set_mod_enable_bitmap(wmi_handle, DBGLOG_LVL_MAX, bitmap, + 2); + } + return 0; +} + +static char *dbglog_get_msg(A_UINT32 moduleid, A_UINT32 debugid) +{ + static char unknown_str[64]; + + if (moduleid < WLAN_MODULE_ID_MAX && debugid < MAX_DBG_MSGS) { + char *str = DBG_MSG_ARR[moduleid][debugid]; + if (str && str[0] != '\0') { + return str; + } + } + + snprintf(unknown_str, sizeof(unknown_str), + "UNKNOWN %u:%u", moduleid, debugid); + + return unknown_str; +} + +static +void dbglog_printf(A_UINT32 timestamp, A_UINT16 vap_id, const char *fmt, ...) +{ + char buf[128]; + va_list ap; + + if (vap_id < DBGLOG_MAX_VDEVID) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, + (DBGLOG_PRINT_PREFIX "[%u] vap-%u ", timestamp, + vap_id)); + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, + (DBGLOG_PRINT_PREFIX "[%u] ", timestamp)); + } + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s\n", buf)); +} + +static void +dbglog_printf_no_line_break(A_UINT32 timestamp, + A_UINT16 vap_id, const char *fmt, ...) +{ + char buf[128]; + va_list ap; + + if (vap_id < DBGLOG_MAX_VDEVID) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, + (DBGLOG_PRINT_PREFIX "[%u] vap-%u ", timestamp, + vap_id)); + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, + (DBGLOG_PRINT_PREFIX "[%u] ", timestamp)); + } + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s", buf)); +} + +#define USE_NUMERIC 0 + +static A_BOOL +dbglog_default_print_handler(A_UINT32 mod_id, A_UINT16 vap_id, A_UINT32 dbg_id, + A_UINT32 timestamp, A_UINT16 numargs, + A_UINT32 *args) +{ + int i; + + if (vap_id < DBGLOG_MAX_VDEVID) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, + (DBGLOG_PRINT_PREFIX "[%u] vap-%u %s ( ", + timestamp, vap_id, dbglog_get_msg(mod_id, + dbg_id))); + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, + (DBGLOG_PRINT_PREFIX "[%u] %s ( ", timestamp, + dbglog_get_msg(mod_id, dbg_id))); + } + + for (i = 0; i < numargs; i++) { +#if USE_NUMERIC + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%u", args[i])); +#else + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%#x", args[i])); +#endif + if ((i + 1) < numargs) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (", ")); + } + } + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (" )\n")); + + return true; +} + +#define DBGLOG_PARSE_ARGS_STRING_LENGTH (DBGLOG_NUM_ARGS_MAX * 11 + 10) +static int dbglog_print_raw_data(A_UINT32 *buffer, A_UINT32 length) +{ + A_UINT32 timestamp; + A_UINT32 debugid; + A_UINT32 moduleid; + A_UINT16 numargs, curArgs; + A_UINT32 count = 0, totalWriteLen, writeLen; + char parseArgsString[DBGLOG_PARSE_ARGS_STRING_LENGTH]; + char *dbgidString; + + while (count < length) { + + debugid = DBGLOG_GET_DBGID(buffer[count + 1]); + moduleid = DBGLOG_GET_MODULEID(buffer[count + 1]); + numargs = DBGLOG_GET_NUMARGS(buffer[count + 1]); + timestamp = DBGLOG_GET_TIME_STAMP(buffer[count]); + + if (moduleid < WLAN_MODULE_ID_MAX && debugid < MAX_DBG_MSGS + && numargs <= DBGLOG_NUM_ARGS_MAX) { + + OS_MEMZERO(parseArgsString, sizeof(parseArgsString)); + totalWriteLen = 0; + + for (curArgs = 0; curArgs < numargs; curArgs++) { + /* Using sprintf_s instead of sprintf, to avoid length overflow */ + writeLen = + snprintf(parseArgsString + totalWriteLen, + DBGLOG_PARSE_ARGS_STRING_LENGTH - + totalWriteLen, "%x ", + buffer[count + 2 + curArgs]); + totalWriteLen += writeLen; + } + + if (debugid < MAX_DBG_MSGS) { + dbgidString = DBG_MSG_ARR[moduleid][debugid]; + if (dbgidString != NULL) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, + ("fw:%s(%x %x):%s\n", + dbgidString, timestamp, + buffer[count + 1], + parseArgsString)); + } else { + /* host need sync with FW id */ + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, + ("fw:%s:m:%x,id:%x(%x %x):%s\n", + "UNKNOWN", moduleid, + debugid, timestamp, + buffer[count + 1], + parseArgsString)); + } + } else if (debugid == + DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG) { + /* specific debugid */ + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, + ("fw:%s:m:%x,id:%x(%x %x):%s\n", + "DBGLOG_SM_MSG", moduleid, + debugid, timestamp, + buffer[count + 1], + parseArgsString)); + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, + ("fw:%s:m:%x,id:%x(%x %x):%s\n", + "UNKNOWN", moduleid, debugid, + timestamp, buffer[count + 1], + parseArgsString)); + } + } + + count += numargs + 2; /* 32 bit Time stamp + 32 bit Dbg header */ + } + + return 0; + +} + +#ifdef WLAN_OPEN_SOURCE +static int +dbglog_debugfs_raw_data(wmi_unified_t wmi_handle, const uint8_t *buf, + A_UINT32 length, A_UINT32 dropped) +{ + struct fwdebug *fwlog = (struct fwdebug *)&wmi_handle->dbglog; + struct dbglog_slot *slot; + struct sk_buff *skb; + size_t slot_len; + + if (WARN_ON(length > ATH6KL_FWLOG_PAYLOAD_SIZE)) + return -ENODEV; + + slot_len = sizeof(*slot) + ATH6KL_FWLOG_PAYLOAD_SIZE; + + skb = alloc_skb(slot_len, GFP_KERNEL); + if (!skb) + return -ENOMEM; + + slot = (struct dbglog_slot *)skb_put(skb, slot_len); + slot->diag_type = (A_UINT32) DIAG_TYPE_FW_DEBUG_MSG; + slot->timestamp = cpu_to_le32(jiffies); + slot->length = cpu_to_le32(length); + slot->dropped = cpu_to_le32(dropped); + memcpy(slot->payload, buf, length); + + /* Need to pad each record to fixed length ATH6KL_FWLOG_PAYLOAD_SIZE */ + memset(slot->payload + length, 0, ATH6KL_FWLOG_PAYLOAD_SIZE - length); + + spin_lock(&fwlog->fwlog_queue.lock); + + __skb_queue_tail(&fwlog->fwlog_queue, skb); + + complete(&fwlog->fwlog_completion); + + /* drop oldest entries */ + while (skb_queue_len(&fwlog->fwlog_queue) > ATH6KL_FWLOG_MAX_ENTRIES) { + skb = __skb_dequeue(&fwlog->fwlog_queue); + kfree_skb(skb); + } + + spin_unlock(&fwlog->fwlog_queue.lock); + + return true; +} +#endif /* WLAN_OPEN_SOURCE */ + +/** + * send_fw_diag_nl_data - pack the data from fw diag event handler + * @buffer: buffer of diag event + * @len: length of the diag event + * @event: the even type + * + * return: 0 if sent successfully, otherwise error code + */ +static int send_fw_diag_nl_data(const uint8_t *buffer, A_UINT32 len, + A_UINT32 event_type) +{ + struct sk_buff *skb_out; + struct nlmsghdr *nlh; + int res = 0; + tAniNlHdr *wnl; + int radio; + int msg_len; + + if (WARN_ON(len > ATH6KL_FWLOG_PAYLOAD_SIZE)) + return -ENODEV; + + if (nl_srv_is_initialized() != 0) + return -EIO; + + radio = cds_get_radio_index(); + if (radio == -EINVAL) + return -EIO; + + if (cds_is_multicast_logging()) { + msg_len = len + sizeof(radio); + skb_out = nlmsg_new(msg_len, GFP_KERNEL); + if (!skb_out) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("Failed to allocate new skb\n")); + return -ENOMEM; + } + nlh = nlmsg_put(skb_out, 0, 0, WLAN_NL_MSG_CNSS_DIAG, msg_len, + 0); + if (!nlh) { + kfree_skb(skb_out); + return -EMSGSIZE; + } + wnl = (tAniNlHdr *)nlh; + wnl->radio = radio; + + /* data buffer offset from nlmsg_hdr + sizeof(int) radio */ + memcpy(nlmsg_data(nlh) + sizeof(radio), buffer, len); + + res = nl_srv_bcast(skb_out); + if ((res < 0) && (res != -ESRCH)) { + AR_DEBUG_PRINTF(ATH_DEBUG_RSVD1, + ("%s: nl_srv_bcast failed 0x%x\n", + __func__, res)); + return res; + } + } + return res; +} + +/** + * process_fw_diag_event_data() - process diag events and fw messages + * @datap: data to be processed + * @num_data: number of data chunks + * + * return: success + */ +static int +process_fw_diag_event_data(uint8_t *datap, uint32_t num_data) +{ + uint32_t i; + uint32_t diag_type; + uint32_t nl_data_len; /* diag hdr + payload */ + uint32_t diag_data_len; /* each fw diag payload */ + struct wlan_diag_data *diag_data; + + for (i = 0; i < num_data; i++) { + diag_data = (struct wlan_diag_data *)datap; + diag_type = WLAN_DIAG_0_TYPE_GET(diag_data->word0); + diag_data_len = WLAN_DIAG_0_LEN_GET(diag_data->word0); + /* Length of diag struct and len of payload */ + nl_data_len = sizeof(struct wlan_diag_data) + diag_data_len; + + switch (diag_type) { + case DIAG_TYPE_FW_EVENT: + return send_fw_diag_nl_data(datap, nl_data_len, + diag_type); + break; + case DIAG_TYPE_FW_LOG: + return send_fw_diag_nl_data(datap, nl_data_len, + diag_type); + break; + } + /* Move to the next event and send to cnss-diag */ + datap += nl_data_len; + } + + return 0; +} + +static int +send_diag_netlink_data(const uint8_t *buffer, A_UINT32 len, A_UINT32 cmd) +{ + struct sk_buff *skb_out; + struct nlmsghdr *nlh; + int res = 0; + struct dbglog_slot *slot; + size_t slot_len; + tAniNlHdr *wnl; + int radio; + + if (WARN_ON(len > ATH6KL_FWLOG_PAYLOAD_SIZE)) + return -ENODEV; + + if (nl_srv_is_initialized() != 0) + return -EIO; + + radio = cds_get_radio_index(); + if (radio == -EINVAL) + return -EIO; + + if (cds_is_multicast_logging()) { + slot_len = sizeof(*slot) + ATH6KL_FWLOG_PAYLOAD_SIZE + + sizeof(radio); + + skb_out = nlmsg_new(slot_len, GFP_KERNEL); + if (!skb_out) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("Failed to allocate new skb\n")); + return -ENOMEM; + } + + nlh = nlmsg_put(skb_out, 0, 0, WLAN_NL_MSG_CNSS_DIAG, + slot_len, 0); + if (!nlh) { + kfree_skb(skb_out); + return -EMSGSIZE; + } + wnl = (tAniNlHdr *)nlh; + wnl->radio = radio; + /* data buffer offset from: nlmsg_hdr + sizeof(int) radio */ + slot = (struct dbglog_slot *) (nlmsg_data(nlh) + sizeof(radio)); + slot->diag_type = cmd; + slot->timestamp = cpu_to_le32(jiffies); + slot->length = cpu_to_le32(len); + /* Version mapped to get_version here */ + slot->dropped = get_version; + memcpy(slot->payload, buffer, len); + + res = nl_srv_bcast(skb_out); + if ((res < 0) && (res != -ESRCH)) { + AR_DEBUG_PRINTF(ATH_DEBUG_RSVD1, + ("%s: nl_srv_bcast failed 0x%x\n", + __func__, res)); + return res; + } + } + return res; +} + +static int +dbglog_process_netlink_data(wmi_unified_t wmi_handle, const uint8_t *buffer, + A_UINT32 len, A_UINT32 dropped) +{ + struct sk_buff *skb_out; + struct nlmsghdr *nlh; + int res = 0; + struct dbglog_slot *slot; + size_t slot_len; + tAniNlHdr *wnl; + int radio; + + if (WARN_ON(len > ATH6KL_FWLOG_PAYLOAD_SIZE)) + return -ENODEV; + + if (nl_srv_is_initialized() != 0) + return -EIO; + + radio = cds_get_radio_index(); + if (radio == -EINVAL) + return -EIO; + + if (cds_is_multicast_logging()) { + slot_len = sizeof(*slot) + ATH6KL_FWLOG_PAYLOAD_SIZE + + sizeof(radio); + + skb_out = nlmsg_new(slot_len, GFP_KERNEL); + if (!skb_out) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("Failed to allocate new skb\n")); + return -ENOMEM; + } + + nlh = nlmsg_put(skb_out, 0, 0, WLAN_NL_MSG_CNSS_DIAG, + slot_len, 0); + if (!nlh) { + kfree_skb(skb_out); + return -EMSGSIZE; + } + wnl = (tAniNlHdr *)nlh; + wnl->radio = radio; + /* data buffer offset from: nlmsg_hdr + sizeof(int) radio */ + slot = (struct dbglog_slot *) (nlmsg_data(nlh) + sizeof(radio)); + slot->diag_type = (A_UINT32) DIAG_TYPE_FW_DEBUG_MSG; + slot->timestamp = cpu_to_le32(jiffies); + slot->length = cpu_to_le32(len); + slot->dropped = cpu_to_le32(dropped); + memcpy(slot->payload, buffer, len); + + res = nl_srv_bcast(skb_out); + if ((res < 0) && (res != -ESRCH)) { + AR_DEBUG_PRINTF(ATH_DEBUG_RSVD1, + ("%s: nl_srv_ucast failed 0x%x\n", + __func__, res)); + return res; + } + } + return res; +} + +/* + * WMI diag data event handler, this function invoked as a CB + * when there DIAG_EVENT, DIAG_MSG, DIAG_DBG to be + * forwarded from the FW. This is the new implementation for + * replacement of fw_dbg and dbg messages + */ + +static int diag_fw_handler(ol_scn_t scn, uint8_t *data, uint32_t datalen) +{ + + tp_wma_handle wma = (tp_wma_handle) scn; + wmitlv_cmd_param_info *param_buf; + uint8_t *datap; + uint32_t len = 0; + uint32_t *buffer; + + if (!wma) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("NULL Pointer assigned\n")); + return -EINVAL; + } + /* when fw asser occurs,host can't use TLV format. */ + if (wma->is_fw_assert) { + datap = data; + len = datalen; + wma->is_fw_assert = 0; + } else { + param_buf = (wmitlv_cmd_param_info *) data; + if (!param_buf) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("Get NULL point message from FW\n")); + return -EINVAL; + } + + param_buf = (wmitlv_cmd_param_info *) data; + datap = param_buf->tlv_ptr; + len = param_buf->num_elements; + if (!get_version) { + buffer = (uint32_t *) datap; + buffer++; /* skip offset */ + if (WLAN_DIAG_TYPE_CONFIG == DIAG_GET_TYPE(*buffer)) { + buffer++; /* skip */ + if (DIAG_VERSION_INFO == DIAG_GET_ID(*buffer)) { + buffer++; /* skip */ + /* get payload */ + get_version = *buffer; + } + } + } + } + if (dbglog_process_type == DBGLOG_PROCESS_PRINT_RAW) { + if (!gprint_limiter) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("NOT Supported" + " only supports net link socket\n")); + gprint_limiter = true; + } + return 0; + } + + if (dbglog_process_type == DBGLOG_PROCESS_NET_RAW) { + return send_diag_netlink_data((A_UINT8 *) datap, + len, DIAG_TYPE_FW_MSG); + } +#ifdef WLAN_OPEN_SOURCE + if (dbglog_process_type == DBGLOG_PROCESS_POOL_RAW) { + if (!gprint_limiter) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("NOT Supported" + " only supports net link socket\n")); + gprint_limiter = true; + } + return 0; + } +#endif /* WLAN_OPEN_SOURCE */ + if (!gprint_limiter) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("NOT Supported" + " only supports net link socket\n")); + gprint_limiter = true; + } + /* Always returns zero */ + return 0; +} + +/* + * WMI diag data event handler, this function invoked as a CB + * when there DIAG_DATA to be forwarded from the FW. + */ +static int +fw_diag_data_event_handler(ol_scn_t scn, uint8_t *data, uint32_t datalen) +{ + + WMI_DIAG_DATA_CONTAINER_EVENTID_param_tlvs *param_buf; + uint8_t *datap; + uint32_t num_data; /* Total events */ + + param_buf = (WMI_DIAG_DATA_CONTAINER_EVENTID_param_tlvs *) data; + if (!param_buf) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("Got NULL point message from FW\n")); + return -EINVAL; + } + + num_data = param_buf->num_bufp; + + datap = (uint8_t *) param_buf->bufp; + + return process_fw_diag_event_data(datap, num_data); +} + +int dbglog_parse_debug_logs(ol_scn_t scn, uint8_t *data, uint32_t datalen) +{ + tp_wma_handle wma = (tp_wma_handle) scn; + A_UINT32 count; + A_UINT32 *buffer; + A_UINT32 timestamp; + A_UINT32 debugid; + A_UINT32 moduleid; + A_UINT16 vapid; + A_UINT16 numargs; + qdf_size_t length; + A_UINT32 dropped; + WMI_DEBUG_MESG_EVENTID_param_tlvs *param_buf; + uint8_t *datap; + uint32_t len; + + if (!wma) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("NULL Pointer assigned\n")); + return -EINVAL; + } + /*when fw asser occurs,host can't use TLV format. */ + if (wma->is_fw_assert) { + datap = data; + len = datalen; + wma->is_fw_assert = 0; + } else { + param_buf = (WMI_DEBUG_MESG_EVENTID_param_tlvs *) data; + if (!param_buf) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("Get NULL point message from FW\n")); + return -EINVAL; + } + + datap = param_buf->bufp; + len = param_buf->num_bufp; + } + + dropped = *((A_UINT32 *) datap); + if (dropped > 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_TRC, + ("%d log buffers are dropped \n", dropped)); + } + datap += sizeof(dropped); + len -= sizeof(dropped); + + count = 0; + buffer = (A_UINT32 *) datap; + length = (len >> 2); + + if (dbglog_process_type == DBGLOG_PROCESS_PRINT_RAW) { + return dbglog_print_raw_data(buffer, length); + } + + if (dbglog_process_type == DBGLOG_PROCESS_NET_RAW) { + return dbglog_process_netlink_data((wmi_unified_t) wma-> + wmi_handle, + (A_UINT8 *) buffer, + len, dropped); + } +#ifdef WLAN_OPEN_SOURCE + if (dbglog_process_type == DBGLOG_PROCESS_POOL_RAW) { + return dbglog_debugfs_raw_data((wmi_unified_t) wma->wmi_handle, + (A_UINT8 *) buffer, len, + dropped); + } +#endif /* WLAN_OPEN_SOURCE */ + + while ((count + 2) < length) { + timestamp = DBGLOG_GET_TIME_STAMP(buffer[count]); + debugid = DBGLOG_GET_DBGID(buffer[count + 1]); + moduleid = DBGLOG_GET_MODULEID(buffer[count + 1]); + vapid = DBGLOG_GET_VDEVID(buffer[count + 1]); + numargs = DBGLOG_GET_NUMARGS(buffer[count + 1]); + + if ((count + 2 + numargs) > length) + return 0; + + if (moduleid >= WLAN_MODULE_ID_MAX) + return 0; + + if (mod_print[moduleid] == NULL) { + /* No module specific log registered use the default handler */ + dbglog_default_print_handler(moduleid, vapid, debugid, + timestamp, numargs, + (((A_UINT32 *) buffer) + + 2 + count)); + } else { + if (! + (mod_print[moduleid] + (moduleid, vapid, debugid, timestamp, numargs, + (((A_UINT32 *) buffer) + 2 + count)))) { + /* The message is not handled by the module specific handler */ + dbglog_default_print_handler(moduleid, vapid, + debugid, timestamp, + numargs, + (((A_UINT32 *) + buffer) + 2 + + count)); + + } + } + + count += numargs + 2; /* 32 bit Time stamp + 32 bit Dbg header */ + } + /* Always returns zero */ + return 0; +} + +void dbglog_reg_modprint(A_UINT32 mod_id, module_dbg_print printfn) +{ + if (!mod_print[mod_id]) { + mod_print[mod_id] = printfn; + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, + ("module print is already registered for this module %d\n", + mod_id)); + } +} + +static void +dbglog_sm_print(A_UINT32 timestamp, + A_UINT16 vap_id, + A_UINT16 numargs, + A_UINT32 *args, + const char *module_prefix, + const char *states[], A_UINT32 num_states, + const char *events[], A_UINT32 num_events) +{ + A_UINT8 type, arg1, arg2, arg3; + A_UINT32 extra, extra2, extra3; + + if (numargs != 4) { + return; + } + + type = (args[0] >> 24) & 0xff; + arg1 = (args[0] >> 16) & 0xff; + arg2 = (args[0] >> 8) & 0xff; + arg3 = (args[0] >> 0) & 0xff; + + extra = args[1]; + extra2 = args[2]; + extra3 = args[3]; + + switch (type) { + case 0: /* state transition */ + if (arg1 < num_states && arg2 < num_states) { + dbglog_printf(timestamp, vap_id, + "%s: %s => %s (%#x, %#x, %#x)", + module_prefix, states[arg1], states[arg2], + extra, extra2, extra3); + } else { + dbglog_printf(timestamp, vap_id, + "%s: %u => %u (%#x, %#x, %#x)", + module_prefix, arg1, arg2, extra, extra2, + extra3); + } + break; + case 1: /* dispatch event */ + if (arg1 < num_states && arg2 < num_events) { + dbglog_printf(timestamp, vap_id, + "%s: %s < %s (%#x, %#x, %#x)", + module_prefix, states[arg1], events[arg2], + extra, extra2, extra3); + } else { + dbglog_printf(timestamp, vap_id, + "%s: %u < %u (%#x, %#x, %#x)", + module_prefix, arg1, arg2, extra, extra2, + extra3); + } + break; + case 2: /* warning */ + switch (arg1) { + case 0: /* unhandled event */ + if (arg2 < num_states && arg3 < num_events) { + dbglog_printf(timestamp, vap_id, + "%s: unhandled event %s in state %s (%#x, %#x, %#x)", + module_prefix, events[arg3], + states[arg2], extra, extra2, + extra3); + } else { + dbglog_printf(timestamp, vap_id, + "%s: unhandled event %u in state %u (%#x, %#x, %#x)", + module_prefix, arg3, arg2, extra, + extra2, extra3); + } + break; + default: + break; + + } + break; + } +} + +static A_BOOL +dbglog_sta_powersave_print_handler(A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, A_UINT32 *args) +{ + static const char *states[] = { + "IDLE", + "ACTIVE", + "SLEEP_TXQ_FLUSH", + "SLEEP_TX_SENT", + "PAUSE", + "SLEEP_DOZE", + "SLEEP_AWAKE", + "ACTIVE_TXQ_FLUSH", + "ACTIVE_TX_SENT", + "PAUSE_TXQ_FLUSH", + "PAUSE_TX_SENT", + "IDLE_TXQ_FLUSH", + "IDLE_TX_SENT", + }; + + static const char *events[] = { + "START", + "STOP", + "PAUSE", + "UNPAUSE", + "TIM", + "DTIM", + "SEND_COMPLETE", + "PRE_SEND", + "RX", + "HWQ_EMPTY", + "PAUSE_TIMEOUT", + "TXRX_INACTIVITY_TIMEOUT", + "PSPOLL_TIMEOUT", + "UAPSD_TIMEOUT", + "DELAYED_SLEEP_TIMEOUT", + "SEND_N_COMPLETE", + "TIDQ_PAUSE_COMPLETE", + "SEND_PSPOLL", + "SEND_SPEC_PSPOLL", + }; + + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "STA PS", + states, QDF_ARRAY_SIZE(states), events, + QDF_ARRAY_SIZE(events)); + break; + case PS_STA_PM_ARB_REQUEST: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "PM ARB request flags=%x, last_time=%x %s: %s", + args[1], args[2], + dbglog_get_module_str(args[0]), + args[3] ? "SLEEP" : "WAKE"); + } + break; + case PS_STA_DELIVER_EVENT: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, "STA PS: %s %s", + (args[0] == 0 ? "PAUSE_COMPLETE" : + (args[0] == 1 ? "UNPAUSE_COMPLETE" : + (args[0] == 2 ? "SLEEP" : + (args[0] == + 3 ? "AWAKE" : "UNKNOWN")))), + (args[1] == + 0 ? "SUCCESS" : (args[1] == + 1 ? "TXQ_FLUSH_TIMEOUT" + : (args[1] == + 2 ? "NO_ACK" + : (args[1] == + 3 ? + "RX_LEAK_TIMEOUT" + : (args[1] == + 4 ? + "PSPOLL_UAPSD_BUSY_TIMEOUT" + : + "UNKNOWN")))))); + } + break; + case PS_STA_PSPOLL_SEQ_DONE: + if (numargs == 5) { + dbglog_printf(timestamp, vap_id, + "STA PS poll: queue=%u comp=%u rsp=%u rsp_dur=%u fc=%x qos=%x %s", + args[0], args[1], args[2], args[3], + (args[4] >> 16) & 0xffff, + (args[4] >> 8) & 0xff, + (args[4] & 0xff) == + 0 ? "SUCCESS" : (args[4] & 0xff) == + 1 ? "NO_ACK" : (args[4] & 0xff) == + 2 ? "DROPPED" : (args[4] & 0xff) == + 3 ? "FILTERED" : (args[4] & 0xff) == + 4 ? "RSP_TIMEOUT" : "UNKNOWN"); + } + break; + case PS_STA_COEX_MODE: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, "STA PS COEX MODE %s", + args[0] ? "ENABLED" : "DISABLED"); + } + break; + case PS_STA_PSPOLL_ALLOW: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "STA PS-Poll %s flags=%x time=%u", + args[0] ? "ALLOW" : "DISALLOW", args[1], + args[2]); + } + break; + case PS_STA_SET_PARAM: + if (numargs == 2) { + struct { + char *name; + int is_time_param; + } params[] = { + { + "MAX_SLEEP_ATTEMPTS", 0 + }, { + "DELAYED_SLEEP", 1 + }, { + "TXRX_INACTIVITY", 1 + }, { + "MAX_TX_BEFORE_WAKE", 0 + }, { + "UAPSD_TIMEOUT", 1 + }, { + "UAPSD_CONFIG", 0 + }, { + "PSPOLL_RESPONSE_TIMEOUT", 1 + }, { + "MAX_PSPOLL_BEFORE_WAKE", 0 + }, { + "RX_WAKE_POLICY", 0 + }, { + "DELAYED_PAUSE_RX_LEAK", 1 + }, { + "TXRX_INACTIVITY_BLOCKED_RETRY", 1 + }, { + "SPEC_WAKE_INTERVAL", 1 + }, { + "MAX_SPEC_NODATA_PSPOLL", 0 + }, { + "ESTIMATED_PSPOLL_RESP_TIME", 1 + }, { + "QPOWER_MAX_PSPOLL_BEFORE_WAKE", 0 + }, { + "QPOWER_ENABLE", 0 + }, + }; + A_UINT32 param = args[0]; + A_UINT32 value = args[1]; + + if (param < QDF_ARRAY_SIZE(params)) { + if (params[param].is_time_param) { + dbglog_printf(timestamp, vap_id, + "STA PS SET_PARAM %s => %u (us)", + params[param].name, + value); + } else { + dbglog_printf(timestamp, vap_id, + "STA PS SET_PARAM %s => %#x", + params[param].name, + value); + } + } else { + dbglog_printf(timestamp, vap_id, + "STA PS SET_PARAM %x => %#x", + param, value); + } + } + break; + case PS_STA_SPECPOLL_TIMER_STARTED: + dbglog_printf(timestamp, vap_id, + "SPEC Poll Timer Started: Beacon time Remaining:%d wakeup interval:%d", + args[0], args[1]); + break; + case PS_STA_SPECPOLL_TIMER_STOPPED: + dbglog_printf(timestamp, vap_id, "SPEC Poll Timer Stopped"); + break; + default: + return false; + } + + return true; +} + +/* IBSS PS sub modules */ +enum wlan_ibss_ps_sub_module { + WLAN_IBSS_PS_SUB_MODULE_IBSS_NW_SM = 0, + WLAN_IBSS_PS_SUB_MODULE_IBSS_SELF_PS = 1, + WLAN_IBSS_PS_SUB_MODULE_IBSS_PEER_PS = 2, + WLAN_IBSS_PS_SUB_MODULE_MAX = 3, +}; + +#define WLAN_IBSS_PS_SUB_MODULE_OFFSET 0x1E + +static A_BOOL +dbglog_ibss_powersave_print_handler(A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, A_UINT32 *args) +{ + static const char *nw_states[] = { + "WAIT_FOR_TBTT", + "ATIM_WINDOW_PRE_BCN", + "ATIM_WINDOW_POST_BCN", + "OUT_OF_ATIM_WINDOW", + "PAUSE_PENDING", + "PAUSED", + }; + + static const char *ps_states[] = { + "ACTIVE", + "SLEEP_TX_SEND", + "SLEEP_DOZE_PAUSE_PENDING", + "SLEEP_DOZE", + "SLEEP_AWAKE", + "ACTIVE_TX_SEND", + "PAUSE_TX_SEND", + "PAUSED", + }; + + static const char *peer_ps_states[] = { + "ACTIVE", + "SLEEP_AWAKE", + "SLEEP_DOZE", + "PS_UNKNOWN", + }; + + static const char *events[] = { + "START", + "STOP", + "SWBA", + "TBTT", + "TX_BCN_CMP", + "SEND_COMPLETE", + "SEND_N_COMPLETE", + "PRE_SEND", + "RX", + "UC_INACTIVITY_TIMEOUT", + "BC_INACTIVITY_TIMEOUT", + "ATIM_WINDOW_BEGIN", + "ATIM_WINDOW_END", + "HWQ_EMPTY", + "UC_ATIM_RCVD", + "TRAFFIC_EXCHANGE_DONE", + "POWER_SAVE_STATE_CHANGE", + "NEW_PEER_JOIN", + "IBSS_VDEV_PAUSE_REQUEST", + "IBSS_VDEV_PAUSE_RESPONSE", + "IBSS_VDEV_PAUSE_TIMEOUT", + "IBSS_VDEV_UNPAUSE_REQUEST", + "PS_STATE_CHANGE", + }; + + enum wlan_ibss_ps_sub_module sub_module; + + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + sub_module = (args[1] >> WLAN_IBSS_PS_SUB_MODULE_OFFSET) & 0x3; + switch (sub_module) { + case WLAN_IBSS_PS_SUB_MODULE_IBSS_NW_SM: + dbglog_sm_print(timestamp, vap_id, numargs, args, + "IBSS PS NW", nw_states, + QDF_ARRAY_SIZE(nw_states), events, + QDF_ARRAY_SIZE(events)); + break; + case WLAN_IBSS_PS_SUB_MODULE_IBSS_SELF_PS: + dbglog_sm_print(timestamp, vap_id, numargs, args, + "IBSS PS Self", ps_states, + QDF_ARRAY_SIZE(ps_states), events, + QDF_ARRAY_SIZE(events)); + break; + case WLAN_IBSS_PS_SUB_MODULE_IBSS_PEER_PS: + dbglog_sm_print(timestamp, vap_id, numargs, args, + "IBSS PS Peer", peer_ps_states, + QDF_ARRAY_SIZE(peer_ps_states), events, + QDF_ARRAY_SIZE(events)); + break; + default: + break; + } + break; + case IBSS_PS_DBGID_PEER_CREATE: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: peer alloc failed for peer ID:%u", + args[0]); + } else if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: create peer ID=%u", args[0]); + } + break; + case IBSS_PS_DBGID_PEER_DELETE: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: delete peer ID=%u num_peers:%d num_sleeping_peers:%d ps_enabled_for_this_peer:%d", + args[0], args[1], args[2], args[3]); + } + break; + case IBSS_PS_DBGID_VDEV_CREATE: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: vdev alloc failed", args[0]); + } else if (numargs == 0) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: vdev created"); + } + break; + case IBSS_PS_DBGID_VDEV_DELETE: + dbglog_printf(timestamp, vap_id, "IBSS PS: vdev deleted"); + break; + + case IBSS_PS_DBGID_VDEV_EVENT: + if (numargs == 1) { + if (args[0] == 5) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: vdev event for peer add"); + } else if (args[0] == 7) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: vdev event for peer delete"); + } else { + dbglog_printf(timestamp, vap_id, + "IBSS PS: vdev event %u", + args[0]); + } + } + break; + + case IBSS_PS_DBGID_PEER_EVENT: + if (numargs == 4) { + if (args[0] == 0xFFFF) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: pre_send for peer:%u peer_type:%u sm_event_mask:%0x", + args[1], args[3], args[2]); + } else if (args[0] == 0x20000) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: send_complete for peer:%u peer_type:%u sm_event_mask:%0x", + args[1], args[3], args[2]); + } else if (args[0] == 0x10) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: send_n_complete for peer:%u peer_type:%u sm_event_mask:%0x", + args[1], args[3], args[2]); + } else if (args[0] == 0x40) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: rx event for peer:%u peer_type:%u sm_event_mask:%0x", + args[1], args[3], args[2]); + } else if (args[0] == 0x4) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: hw_q_empty for peer:%u peer_type:%u sm_event_mask:%0x", + args[1], args[3], args[2]); + } + } + break; + + case IBSS_PS_DBGID_DELIVER_CAB: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: Deliver CAB n_mpdu:%d send_flags:%0x tid_cur:%d q_depth_for_other_tid:%d", + args[0], args[1], args[2], args[3]); + } + break; + + case IBSS_PS_DBGID_DELIVER_UC_DATA: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: Deliver UC data peer:%d tid:%d n_mpdu:%d send_flags:%0x", + args[0], args[1], args[2], args[3]); + } + break; + + case IBSS_PS_DBGID_DELIVER_UC_DATA_ERROR: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: Deliver UC data error peer:%d tid:%d allowed_tidmask:%0x, pending_tidmap:%0x", + args[0], args[1], args[2], args[3]); + } + break; + + case IBSS_PS_DBGID_UC_INACTIVITY_TMR_RESTART: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: UC timer restart peer:%d timer_val:%0x", + args[0], args[1]); + } + break; + + case IBSS_PS_DBGID_MC_INACTIVITY_TMR_RESTART: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: MC timer restart timer_val:%0x", + args[0]); + } + break; + + case IBSS_PS_DBGID_NULL_TX_COMPLETION: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: null tx completion peer:%d tx_completion_status:%d flags:%0x", + args[0], args[1], args[2]); + } + break; + + case IBSS_PS_DBGID_ATIM_TIMER_START: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: ATIM timer start tsf:%0x %0x tbtt:%0x %0x", + args[0], args[1], args[2], args[3]); + } + break; + + case IBSS_PS_DBGID_UC_ATIM_SEND: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: Send ATIM to peer:%d", args[1]); + } else if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: no peers to send UC ATIM", + args[1]); + } + break; + + case IBSS_PS_DBGID_BC_ATIM_SEND: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: MC Data, num_of_peers:%d bc_atim_sent:%d", + args[1], args[0]); + } + break; + + case IBSS_PS_DBGID_UC_TIMEOUT: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: UC timeout for peer:%d send_null:%d", + args[0], args[1]); + } + break; + + case IBSS_PS_DBGID_PWR_COLLAPSE_ALLOWED: + dbglog_printf(timestamp, vap_id, + "IBSS PS: allow power collapse"); + break; + + case IBSS_PS_DBGID_PWR_COLLAPSE_NOT_ALLOWED: + if (numargs == 0) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: power collapse not allowed by INI"); + } else if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: power collapse not allowed since peer id:%d is not PS capable", + args[0]); + } else if (numargs == 2) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: power collapse not allowed - no peers in NW"); + } else if (numargs == 3) { + if (args[0] == 2) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: power collapse not allowed, non-zero qdepth %d %d", + args[1], args[2]); + } else if (args[0] == 3) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: power collapse not allowed by peer:%d peer_flags:%0x", + args[1], args[2]); + } + } else if (numargs == 5) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: power collapse not allowed by state m/c nw_cur_state:%d nw_next_state:%d ps_cur_state:%d flags:%0x", + args[1], args[2], args[3], args[4]); + } + break; + + case IBSS_PS_DBGID_SET_PARAM: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: Set Param ID:%0x Value:%0x", + args[0], args[1]); + } + break; + + case IBSS_PS_DBGID_HOST_TX_PAUSE: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: Pausing host, vdev_map:%0x", + args[0]); + } + break; + + case IBSS_PS_DBGID_HOST_TX_UNPAUSE: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: Unpausing host, vdev_map:%0x", + args[0]); + } + break; + case IBSS_PS_DBGID_PS_DESC_BIN_LWM: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: LWM, vdev_map:%0x", args[0]); + } + break; + + case IBSS_PS_DBGID_PS_DESC_BIN_HWM: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: HWM, vdev_map:%0x", args[0]); + } + break; + + case IBSS_PS_DBGID_PS_KICKOUT_PEER: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: Kickout peer id:%d atim_fail_cnt:%d status:%d", + args[0], args[1], args[2]); + } + break; + + case IBSS_PS_DBGID_SET_PEER_PARAM: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: Set Peer Id:%d Param ID:%0x Value:%0x", + args[0], args[1], args[2]); + } + break; + + case IBSS_PS_DBGID_BCN_ATIM_WIN_MISMATCH: + if (numargs == 4) { + if (args[0] == 0xDEAD) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: ATIM window length mismatch, our's:%d, peer id:%d, peer's:%d", + args[1], args[2], args[3]); + } else if (args[0] == 0xBEEF) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: Peer ATIM window length changed, peer id:%d, peer recorded atim window:%d new atim window:%d", + args[1], args[2], args[3]); + } + } + break; + + case IBSS_PS_DBGID_RX_CHAINMASK_CHANGE: + if (numargs == 2) { + if (args[1] == 0x1) { + dbglog_printf(timestamp, vap_id, + "IBSS PS: Voting for low power chainmask from :%d", + args[0]); + } else { + dbglog_printf(timestamp, vap_id, + "IBSS PS: Voting for high power chainmask from :%d", + args[0]); + } + } + break; + + default: + return false; + } + + return true; +} + +static +A_BOOL dbglog_ratectrl_print_handler(A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, A_UINT32 *args) +{ + switch (dbg_id) { + case RATECTRL_DBGID_ASSOC: + dbglog_printf(timestamp, vap_id, + "RATE: ChainMask %d, phymode %d, ni_flags 0x%08x, vht_mcs_set 0x%04x, ht_mcs_set 0x%04x", + args[0], args[1], args[2], args[3], args[4]); + break; + case RATECTRL_DBGID_NSS_CHANGE: + dbglog_printf(timestamp, vap_id, "RATE: NEW NSS %d\n", args[0]); + break; + case RATECTRL_DBGID_CHAINMASK_ERR: + dbglog_printf(timestamp, vap_id, + "RATE: Chainmask ERR %d %d %d\n", args[0], + args[1], args[2]); + break; + case RATECTRL_DBGID_UNEXPECTED_FRAME: + dbglog_printf(timestamp, vap_id, + "RATE: WARN1: rate %d flags 0x%08x\n", args[0], + args[1]); + break; + case RATECTRL_DBGID_WAL_RCQUERY: + dbglog_printf(timestamp, vap_id, + "ratectrl_dbgid_wal_rcquery [rix1 %d rix2 %d rix3 %d proberix %d ppduflag 0x%x] ", + args[0], args[1], args[2], args[3], args[4]); + break; + case RATECTRL_DBGID_WAL_RCUPDATE: + dbglog_printf(timestamp, vap_id, + "ratectrl_dbgid_wal_rcupdate [numelems %d ppduflag 0x%x] ", + args[0], args[1]); + break; + case RATECTRL_DBGID_GTX_UPDATE: + { + switch (args[0]) { + case 255: + dbglog_printf(timestamp, vap_id, + "GtxInitPwrCfg [bw[last %d|cur %d] rtcode 0x%x tpc %d tpc_init_pwr_cfg %d] ", + args[1] >> 8, args[1] & 0xff, + args[2], args[3], args[4]); + break; + case 254: + dbglog_printf(timestamp, vap_id, + "gtx_cfg_addr [RTMask0@0x%x PERThreshold@0x%x gtxTPCMin@0x%x userGtxMask@0x%x] ", + args[1], args[2], args[3], + args[4]); + break; + default: + dbglog_printf(timestamp, vap_id, + "gtx_update [act %d bw %d rix 0x%x tpc %d per %d lastrssi %d] ", + args[0], args[1], args[2], + args[3], args[4], args[5]); + } + } + break; + } + return true; +} + +static +A_BOOL dbglog_ani_print_handler(A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, A_UINT32 *args) +{ + switch (dbg_id) { + case ANI_DBGID_ENABLE: + dbglog_printf(timestamp, vap_id, "ANI Enable: %d", args[0]); + break; + case ANI_DBGID_POLL: + dbglog_printf(timestamp, vap_id, + "ANI POLLING: AccumListenTime %d ListenTime %d ofdmphyerr %d cckphyerr %d", + args[0], args[1], args[2], args[3]); + break; + case ANI_DBGID_RESTART: + dbglog_printf(timestamp, vap_id, "ANI Restart"); + break; + case ANI_DBGID_CURRENT_LEVEL: + dbglog_printf(timestamp, vap_id, + "ANI CURRENT LEVEL ofdm level %d cck level %d", + args[0], args[1]); + break; + case ANI_DBGID_OFDM_LEVEL: + dbglog_printf(timestamp, vap_id, + "ANI UPDATE ofdm level %d firstep %d firstep_low %d cycpwr_thr %d self_corr_low %d", + args[0], args[1], args[2], args[3], args[4]); + break; + case ANI_DBGID_CCK_LEVEL: + dbglog_printf(timestamp, vap_id, + "ANI UPDATE cck level %d firstep %d firstep_low %d mrc_cck %d", + args[0], args[1], args[2], args[3]); + break; + case ANI_DBGID_CONTROL: + dbglog_printf(timestamp, vap_id, + "ANI CONTROL ofdmlevel %d ccklevel %d\n", + args[0]); + + break; + case ANI_DBGID_OFDM_PARAMS: + dbglog_printf(timestamp, vap_id, + "ANI ofdm_control firstep %d cycpwr %d\n", + args[0], args[1]); + break; + case ANI_DBGID_CCK_PARAMS: + dbglog_printf(timestamp, vap_id, + "ANI cck_control mrc_cck %d barker_threshold %d\n", + args[0], args[1]); + break; + case ANI_DBGID_RESET: + dbglog_printf(timestamp, vap_id, + "ANI resetting resetflag %d resetCause %8x channel index %d", + args[0], args[1], args[2]); + break; + case ANI_DBGID_SELF_CORR_LOW: + dbglog_printf(timestamp, vap_id, "ANI self_corr_low %d", + args[0]); + break; + case ANI_DBGID_FIRSTEP: + dbglog_printf(timestamp, vap_id, + "ANI firstep %d firstep_low %d", args[0], + args[1]); + break; + case ANI_DBGID_MRC_CCK: + dbglog_printf(timestamp, vap_id, "ANI mrc_cck %d", args[0]); + break; + case ANI_DBGID_CYCPWR: + dbglog_printf(timestamp, vap_id, "ANI cypwr_thresh %d", + args[0]); + break; + case ANI_DBGID_POLL_PERIOD: + dbglog_printf(timestamp, vap_id, + "ANI Configure poll period to %d", args[0]); + break; + case ANI_DBGID_LISTEN_PERIOD: + dbglog_printf(timestamp, vap_id, + "ANI Configure listen period to %d", args[0]); + break; + case ANI_DBGID_OFDM_LEVEL_CFG: + dbglog_printf(timestamp, vap_id, + "ANI Configure ofdm level to %d", args[0]); + break; + case ANI_DBGID_CCK_LEVEL_CFG: + dbglog_printf(timestamp, vap_id, + "ANI Configure cck level to %d", args[0]); + break; + default: + dbglog_printf(timestamp, vap_id, "ANI arg1 %d arg2 %d arg3 %d", + args[0], args[1], args[2]); + break; + } + return true; +} + +static A_BOOL +dbglog_ap_powersave_print_handler(A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, A_UINT32 *args) +{ + switch (dbg_id) { + case AP_PS_DBGID_UPDATE_TIM: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, + "AP PS: TIM update AID=%u %s", + args[0], args[1] ? "set" : "clear"); + } + break; + case AP_PS_DBGID_PEER_STATE_CHANGE: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u power save %s", + args[0], + args[1] ? "enabled" : "disabled"); + } + break; + case AP_PS_DBGID_PSPOLL: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u pspoll response tid=%u flags=%x", + args[0], args[1], args[2]); + } + break; + case AP_PS_DBGID_PEER_CREATE: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "AP PS: create peer AID=%u", args[0]); + } + break; + case AP_PS_DBGID_PEER_DELETE: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "AP PS: delete peer AID=%u", args[0]); + } + break; + case AP_PS_DBGID_VDEV_CREATE: + dbglog_printf(timestamp, vap_id, "AP PS: vdev create"); + break; + case AP_PS_DBGID_VDEV_DELETE: + dbglog_printf(timestamp, vap_id, "AP PS: vdev delete"); + break; + case AP_PS_DBGID_SYNC_TIM: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u advertised=%#x buffered=%#x", + args[0], args[1], args[2]); + } + break; + case AP_PS_DBGID_NEXT_RESPONSE: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u select next response %s%s%s", + args[0], args[1] ? "(usp active) " : "", + args[2] ? "(pending usp) " : "", + args[3] ? "(pending poll response)" : ""); + } + break; + case AP_PS_DBGID_START_SP: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u START SP tsf=%#x (%u)", + args[0], args[1], args[2]); + } + break; + case AP_PS_DBGID_COMPLETED_EOSP: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u EOSP eosp_tsf=%#x trigger_tsf=%#x", + args[0], args[1], args[2]); + } + break; + case AP_PS_DBGID_TRIGGER: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u TRIGGER tsf=%#x %s%s", + args[0], args[1], + args[2] ? "(usp active) " : "", + args[3] ? "(send_n in progress)" : ""); + } + break; + case AP_PS_DBGID_DUPLICATE_TRIGGER: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u DUP TRIGGER tsf=%#x seq=%u ac=%u", + args[0], args[1], args[2], args[3]); + } + break; + case AP_PS_DBGID_UAPSD_RESPONSE: + if (numargs == 5) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u UAPSD response tid=%u, n_mpdu=%u flags=%#x max_sp=%u current_sp=%u", + args[0], args[1], args[2], args[3], + (args[4] >> 16) & 0xffff, + args[4] & 0xffff); + } + break; + case AP_PS_DBGID_SEND_COMPLETE: + if (numargs == 5) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u SEND_COMPLETE fc=%#x qos=%#x %s%s", + args[0], args[1], args[2], + args[3] ? "(usp active) " : "", + args[4] ? "(pending poll response)" : ""); + } + break; + case AP_PS_DBGID_SEND_N_COMPLETE: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u SEND_N_COMPLETE %s%s", + args[0], + args[1] ? "(usp active) " : "", + args[2] ? "(pending poll response)" : ""); + } + break; + case AP_PS_DBGID_DETECT_OUT_OF_SYNC_STA: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "AP PS: AID=%u detected out-of-sync now=%u tx_waiting=%u txq_depth=%u", + args[0], args[1], args[2], args[3]); + } + break; + case AP_PS_DBGID_DELIVER_CAB: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "AP PS: CAB %s n_mpdus=%u, flags=%x, extra=%u", + (args[0] == 17) ? "MGMT" : "DATA", + args[1], args[2], args[3]); + } + break; + default: + return false; + } + + return true; +} + +static A_BOOL +dbglog_wal_print_handler(A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, A_UINT16 numargs, A_UINT32 *args) +{ + static const char *states[] = { + "ACTIVE", + "WAIT", + "WAIT_FILTER", + "PAUSE", + "PAUSE_SEND_N", + "BLOCK", + }; + + static const char *events[] = { + "PAUSE", + "PAUSE_FILTER", + "UNPAUSE", + + "BLOCK", + "BLOCK_FILTER", + "UNBLOCK", + + "HWQ_EMPTY", + "ALLOW_N", + }; + +#define WAL_VDEV_TYPE(type) \ + (type == 0 ? "AP" : \ + (type == 1 ? "STA" : \ + (type == 2 ? "IBSS" : \ + (type == 2 ? "MONITOR" : \ + "UNKNOWN")))) + +#define WAL_SLEEP_STATE(state) \ + (state == 1 ? "NETWORK SLEEP" : \ + (state == 2 ? "AWAKE" : \ + (state == 3 ? "SYSTEM SLEEP" : \ + "UNKNOWN"))) + + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "TID PAUSE", + states, QDF_ARRAY_SIZE(states), events, + QDF_ARRAY_SIZE(events)); + break; + case WAL_DBGID_SET_POWER_STATE: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "WAL %s => %s, req_count=%u", + WAL_SLEEP_STATE(args[0]), + WAL_SLEEP_STATE(args[1]), args[2]); + } + break; + case WAL_DBGID_CHANNEL_CHANGE_FORCE_RESET: + if (numargs == 4) { + dbglog_printf(timestamp, vap_id, + "WAL channel change (force reset) freq=%u, flags=%u mode=%u rx_ok=%u tx_ok=%u", + args[0] & 0x0000ffff, + (args[0] & 0xffff0000) >> 16, args[1], + args[2], args[3]); + } + break; + case WAL_DBGID_CHANNEL_CHANGE: + if (numargs == 2) { + dbglog_printf(timestamp, vap_id, + "WAL channel change freq=%u, mode=%u flags=%u rx_ok=1 tx_ok=1", + args[0] & 0x0000ffff, + (args[0] & 0xffff0000) >> 16, args[1]); + } + break; + case WAL_DBGID_VDEV_START: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, "WAL %s vdev started", + WAL_VDEV_TYPE(args[0])); + } + break; + case WAL_DBGID_VDEV_STOP: + dbglog_printf(timestamp, vap_id, "WAL %s vdev stopped", + WAL_VDEV_TYPE(args[0])); + break; + case WAL_DBGID_VDEV_UP: + dbglog_printf(timestamp, vap_id, "WAL %s vdev up, count=%u", + WAL_VDEV_TYPE(args[0]), args[1]); + break; + case WAL_DBGID_VDEV_DOWN: + dbglog_printf(timestamp, vap_id, "WAL %s vdev down, count=%u", + WAL_VDEV_TYPE(args[0]), args[1]); + break; + case WAL_DBGID_TX_MGMT_DESCID_SEQ_TYPE_LEN: + dbglog_printf(timestamp, vap_id, + "WAL Tx Mgmt frame desc_id=0x%x, seq=0x%x, type=0x%x, len=0x%x islocal=0x%x", + args[0], args[1], args[2], + (args[3] & 0xffff0000) >> 16, + args[3] & 0x0000ffff); + break; + case WAL_DBGID_TX_MGMT_COMP_DESCID_STATUS: + dbglog_printf(timestamp, vap_id, + "WAL Tx Mgmt frame completion desc_id=0x%x, status=0x%x, islocal=0x%x", + args[0], args[1], args[2]); + break; + case WAL_DBGID_TX_DATA_MSDUID_SEQ_TYPE_LEN: + dbglog_printf(timestamp, vap_id, + "WAL Tx Data frame msdu_id=0x%x, seq=0x%x, type=0x%x, len=0x%x", + args[0], args[1], args[2], args[3]); + break; + case WAL_DBGID_TX_DATA_COMP_MSDUID_STATUS: + dbglog_printf(timestamp, vap_id, + "WAL Tx Data frame completion desc_id=0x%x, status=0x%x, seq=0x%x", + args[0], args[1], args[2]); + break; + case WAL_DBGID_RESET_PCU_CYCLE_CNT: + dbglog_printf(timestamp, vap_id, + "WAL PCU cycle counter value at reset:%x", + args[0]); + break; + case WAL_DBGID_TX_DISCARD: + dbglog_printf(timestamp, vap_id, + "WAL Tx enqueue discard msdu_id=0x%x", args[0]); + break; + case WAL_DBGID_SET_HW_CHAINMASK: + dbglog_printf(timestamp, vap_id, "WAL_DBGID_SET_HW_CHAINMASK " + "pdev=%d, txchain=0x%x, rxchain=0x%x", + args[0], args[1], args[2]); + break; + case WAL_DBGID_SET_HW_CHAINMASK_TXRX_STOP_FAIL: + dbglog_printf(timestamp, vap_id, + "WAL_DBGID_SET_HW_CHAINMASK_TXRX_STOP_FAIL rxstop=%d, txstop=%d", + args[0], args[1]); + break; + case WAL_DBGID_GET_HW_CHAINMASK: + dbglog_printf(timestamp, vap_id, "WAL_DBGID_GET_HW_CHAINMASK " + "txchain=0x%x, rxchain=0x%x", args[0], args[1]); + break; + case WAL_DBGID_SMPS_DISABLE: + dbglog_printf(timestamp, vap_id, "WAL_DBGID_SMPS_DISABLE"); + break; + case WAL_DBGID_SMPS_ENABLE_HW_CNTRL: + dbglog_printf(timestamp, vap_id, + "WAL_DBGID_SMPS_ENABLE_HW_CNTRL low_pwr_mask=0x%x, high_pwr_mask=0x%x", + args[0], args[1]); + break; + case WAL_DBGID_SMPS_SWSEL_CHAINMASK: + dbglog_printf(timestamp, vap_id, + "WAL_DBGID_SMPS_SWSEL_CHAINMASK low_pwr=0x%x, chain_mask=0x%x", + args[0], args[1]); + break; + default: + return false; + } + + return true; +} + +static A_BOOL +dbglog_scan_print_handler(A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, A_UINT16 numargs, A_UINT32 *args) +{ + static const char *states[] = { + "IDLE", + "BSSCHAN", + "WAIT_FOREIGN_CHAN", + "FOREIGN_CHANNEL", + "TERMINATING" + }; + + static const char *events[] = { + "REQ", + "STOP", + "BSSCHAN", + "FOREIGN_CHAN", + "CHECK_ACTIVITY", + "REST_TIME_EXPIRE", + "DWELL_TIME_EXPIRE", + "PROBE_TIME_EXPIRE", + }; + + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "SCAN", + states, QDF_ARRAY_SIZE(states), events, + QDF_ARRAY_SIZE(events)); + break; + default: + return false; + } + + return true; +} + +static +A_BOOL dbglog_coex_print_handler(A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, A_UINT32 *args) +{ + A_UINT8 i; + char *dbg_id_str; + + static const char *wlan_rx_xput_status[] = { + "WLAN_XPUT_NORMAL", + "WLAN_XPUT_UNDER_THRESH", + "WLAN_XPUT_CRITICAL", + "WLAN_XPUT_RECOVERY_TIMEOUT", + }; + + static const char *coex_sched_req[] = { + "SCHED_REQ_NEXT", + "SCHED_REQ_BT", + "SCHED_REQ_WLAN", + "SCHED_REQ_POSTPAUSE", + "SCHED_REQ_UNPAUSE", + }; + + static const char *coex_sched_type[] = { + "SCHED_NONE", + "SCHED_WLAN", + "SCHED_BT", + "SCHED_WLAN_PAUSE", + "SCHED_WLAN_POSTPAUSE", + "SCHED_WLAN_UNPAUSE", + "COEX_SCHED_MWS", + }; + + static const char *coex_trf_mgmt_type[] = { + "TRF_MGMT_FREERUN", + "TRF_MGMT_SHAPE_PM", + "TRF_MGMT_SHAPE_PSP", + "TRF_MGMT_SHAPE_S_CTS", + "TRF_MGMT_SHAPE_OCS", + "TRF_MGMT_SHAPE_FIXED_TIME", + "TRF_MGMT_SHAPE_NOA", + "TRF_MGMT_SHAPE_OCS_CRITICAL", + "TRF_MGMT_NONE", + }; + + static const char *coex_system_status[] = { + "ALL_OFF", + "BTCOEX_NOT_REQD", + "WLAN_IS_IDLE", + "EXECUTE_SCHEME", + "BT_FULL_CONCURRENCY", + "WLAN_SLEEPING", + "WLAN_IS_PAUSED", + "WAIT_FOR_NEXT_ACTION", + "SOC_WAKE", + }; + + static const char *wlan_rssi_type[] = { + "LOW_RSSI", + "MID_RSSI", + "HI_RSSI", + "INVALID_RSSI", + }; + + static const char *coex_bt_scheme[] = { + "IDLE_CTRL", + "ACTIVE_ASYNC_CTRL", + "PASSIVE_SYNC_CTRL", + "ACTIVE_SYNC_CTRL", + "DEFAULT_CTRL", + "CONCURRENCY_CTRL", + }; + + static const char *wal_peer_rx_rate_stats_event_sent[] = { + "PR_RX_EVT_SENT_NONE", + "PR_RX_EVT_SENT_LOWER", + "PR_RX_EVT_SENT_UPPER", + }; + + static const char *wlan_psp_stimulus[] = { + "ENTRY", + "EXIT", + "PS_READY", + "PS_NOT_READY", + "RX_MORE_DATA_RCVD", + "RX_NO_MORE_DATA_RCVD", + "TX_DATA_COMPLT", + "TX_COMPLT", + "TIM_SET", + "REQ", + "DONE_SUCCESS", + "DONE_NO_PS_POLL_ACK", + "DONE_RESPONSE_TMO", + "DONE_DROPPED", + "DONE_FILTERED", + "WLAN_START", + "NONWLAN_START", + "NONWLAN_INTVL_UPDATE", + "NULL_TX", + "NULL_TX_COMPLT", + "BMISS_FIRST", + "NULL_TX_FAIL", + "RX_NO_MORE_DATA_DATAFRM", + }; + + static const char *coex_pspoll_state[] = { + "STATE_DISABLED", + "STATE_NOT_READY", + "STATE_ENABLED", + "STATE_READY", + "STATE_TX_STATUS", + "STATE_RX_STATUS", + }; + + static const char *coex_scheduler_interval[] = { + "COEX_SCHED_NONWLAN_INT", + "COEX_SCHED_WLAN_INT", + }; + + static const char *wlan_weight[] = { + "BT_COEX_BASE", + "BT_COEX_LOW", + "BT_COEX_MID", + "BT_COEX_MID_NONSYNC", + "BT_COEX_HI_NONVOICE", + "BT_COEX_HI", + "BT_COEX_CRITICAL", + }; + + static const char *wlan_power_state[] = { + "SLEEP", + "AWAKE", + "FULL_SLEEP", + }; + + static const char *coex_psp_error_type[] = { + "DISABLED_STATE", + "VDEV_NULL", + "COEX_PSP_ENTRY", + "ZERO_INTERVAL", + "COEX_PSP_EXIT", + "READY_DISABLED", + "READY_NOT_DISABLED", + "POLL_PKT_DROPPED", + "SET_TIMER_PARAM", + }; + + static const char *wlan_phymode[] = { + "A", + "G", + "B", + "G_ONLY", + "NA_HT20", + "NG_HT20", + "NA_HT40", + "NG_HT40", + "AC_VHT20", + "AC_VHT40", + "AC_VHT80", + "AC_VHT20_2G", + "AC_VHT40_2G", + "AC_VHT80_2G", + "UNKNOWN", + }; + + static const char *wlan_curr_band[] = { + "2G", + "5G", + }; + + dbg_id_str = dbglog_get_msg(mod_id, dbg_id); + + switch (dbg_id) { + case COEX_SYSTEM_UPDATE: + if (numargs == 1 && args[0] < 9) { + dbglog_printf(timestamp, vap_id, "%s: %s", dbg_id_str, + coex_system_status[args[0]]); + } else if (numargs >= 5 && args[0] < 9 && args[2] < 9) { + dbglog_printf(timestamp, vap_id, + "%s: %s, WlanSysState(0x%x), %s, NumChains(%u), AggrLimit(%u)", + dbg_id_str, coex_system_status[args[0]], + args[1], coex_trf_mgmt_type[args[2]], + args[3], args[4]); + } else { + return false; + } + break; + case COEX_SCHED_START: + if (numargs >= 5 && args[0] < 5 && args[2] < 9 && args[3] < 4 + && args[4] < 4) { + if (args[1] == 0xffffffff) { + dbglog_printf(timestamp, vap_id, + "%s: %s, DETERMINE_DURATION, %s, %s, %s", + dbg_id_str, + coex_sched_req[args[0]], + coex_trf_mgmt_type[args[2]], + wlan_rx_xput_status[args[3]], + wlan_rssi_type[args[4]]); + } else { + dbglog_printf(timestamp, vap_id, + "%s: %s, IntvlDur(%u), %s, %s, %s", + dbg_id_str, + coex_sched_req[args[0]], args[1], + coex_trf_mgmt_type[args[2]], + wlan_rx_xput_status[args[3]], + wlan_rssi_type[args[4]]); + } + } else { + return false; + } + break; + case COEX_SCHED_RESULT: + if (numargs >= 5 && args[0] < 5 && args[1] < 9 && args[2] < 9) { + dbglog_printf(timestamp, vap_id, + "%s: %s, %s, %s, CoexMgrPolicy(%u), IdleOverride(%u)", + dbg_id_str, coex_sched_req[args[0]], + coex_trf_mgmt_type[args[1]], + coex_trf_mgmt_type[args[2]], args[3], + args[4]); + } else { + return false; + } + break; + case COEX_BT_SCHEME: + if (numargs >= 1 && args[0] < 6) { + dbglog_printf(timestamp, vap_id, "%s: %s", dbg_id_str, + coex_bt_scheme[args[0]]); + } else { + return false; + } + break; + case COEX_TRF_FREERUN: + if (numargs >= 5 && args[0] < 7) { + dbglog_printf(timestamp, vap_id, + "%s: %s, AllocatedBtIntvls(%u), BtIntvlCnt(%u), AllocatedWlanIntvls(%u), WlanIntvlCnt(%u)", + dbg_id_str, coex_sched_type[args[0]], + args[1], args[2], args[3], args[4]); + } else { + return false; + } + break; + case COEX_TRF_SHAPE_PM: /* used by ocs now */ + if (numargs >= 3) { + dbglog_printf(timestamp, vap_id, + "%s: IntvlLength(%u), BtDuration(%u), WlanDuration(%u)", + dbg_id_str, args[0], args[1], args[2]); + } else { + return false; + } + break; + case COEX_SYSTEM_MONITOR: + if (numargs >= 5 && args[1] < 4 && args[4] < 4) { + dbglog_printf(timestamp, vap_id, + "%s: WlanRxCritical(%u), %s, MinDirectRxRate(%u), MonitorActiveNum(%u), %s", + dbg_id_str, args[0], + wlan_rx_xput_status[args[1]], args[2], + args[3], wlan_rssi_type[args[4]]); + } else { + return false; + } + break; + case COEX_RX_RATE: + if (numargs >= 5 && args[4] < 3) { + dbglog_printf(timestamp, vap_id, + "%s: NumUnderThreshPeers(%u), MinDirectRate(%u), LastRateSample(%u), DeltaT(%u), %s", + dbg_id_str, args[0], args[1], args[2], + args[3], + wal_peer_rx_rate_stats_event_sent[args + [4]]); + } else { + return false; + } + break; + case COEX_WLAN_INTERVAL_START: + if (numargs >= 5) { + dbglog_printf(timestamp, vap_id, + "%s: WlanIntvlCnt(%u), Duration(%u), Weight(%u), BaseIdleOverride(%u), WeightMat[0](0x%x)", + dbg_id_str, args[0], args[1], args[2], + args[3], args[4]); + } else { + return false; + } + break; + case COEX_WLAN_POSTPAUSE_INTERVAL_START: + if (numargs >= 4) { + dbglog_printf(timestamp, vap_id, + "%s: WlanPostPauseIntvlCnt(%u), XputMonitorActiveNum(%u), Duration(%u), Weight(%u)", + dbg_id_str, args[0], args[1], args[2], + args[3]); + } else { + return false; + } + break; + case COEX_BT_INTERVAL_START: + if (numargs >= 5) { + dbglog_printf(timestamp, vap_id, + "%s: BtIntvlCnt(%u), Duration(%u), Weight(%u), BaseIdleOverride(%u), WeightMat[0](0x%x), ", + dbg_id_str, args[0], args[1], args[2], + args[3], args[4]); + } else { + return false; + } + break; + case COEX_POWER_CHANGE: + if (numargs >= 3 && args[1] < 3 && args[2] < 3) { + dbglog_printf(timestamp, vap_id, + "%s: Event(0x%x) %s->%s", dbg_id_str, + args[0], wlan_power_state[args[1]], + wlan_power_state[args[2]]); + } else { + return false; + } + break; + case COEX_CHANNEL_CHANGE: + if (numargs >= 5 && args[3] < 2 && args[4] < 15) { + dbglog_printf(timestamp, vap_id, + "%s: %uMhz->%uMhz, WlanSysState(0x%x), CurrBand(%s), PhyMode(%s)", + dbg_id_str, args[0], args[1], args[2], + wlan_curr_band[args[3]], + wlan_phymode[args[4]]); + } else { + return false; + } + break; + case COEX_PSP_MGR_ENTER: + if (numargs >= 5 && args[0] < 23 && args[1] < 6 && args[3] < 2) { + dbglog_printf(timestamp, vap_id, + "%s: %s, %s, PsPollAvg(%u), %s, CurrT(%u)", + dbg_id_str, wlan_psp_stimulus[args[0]], + coex_pspoll_state[args[1]], args[2], + coex_scheduler_interval[args[3]], + args[4]); + } else { + return false; + } + break; + /* Translate following into decimal */ + case COEX_SINGLECHAIN_DBG_1: + case COEX_SINGLECHAIN_DBG_2: + case COEX_SINGLECHAIN_DBG_3: + case COEX_MULTICHAIN_DBG_1: + case COEX_MULTICHAIN_DBG_2: + case COEX_MULTICHAIN_DBG_3: + case BTCOEX_DBG_MCI_1: + case BTCOEX_DBG_MCI_2: + case BTCOEX_DBG_MCI_3: + case BTCOEX_DBG_MCI_4: + case BTCOEX_DBG_MCI_5: + case BTCOEX_DBG_MCI_6: + case BTCOEX_DBG_MCI_7: + case BTCOEX_DBG_MCI_8: + case BTCOEX_DBG_MCI_9: + case BTCOEX_DBG_MCI_10: + + if (numargs > 0) { + dbglog_printf_no_line_break(timestamp, vap_id, "%s: %u", + dbg_id_str, args[0]); + for (i = 1; i < numargs; i++) { + printk(", %u", args[i]); + } + printk("\n"); + } else { + return false; + } + break; + case COEX_LinkID: + if (numargs >= 4) { + if (args[0]) { /* Add profile */ + dbglog_printf(timestamp, vap_id, + "%s Alloc: LocalID(%u), RemoteID(%u), MinFreeLocalID(%u)", + dbg_id_str, args[1], args[2], + args[3]); + } else { /* Remove profile */ + dbglog_printf(timestamp, vap_id, + "%s Dealloc: LocalID(%u), RemoteID(%u), MinFreeLocalID(%u)", + dbg_id_str, args[1], args[2], + args[3]); + } + } else { + return false; + } + break; + case COEX_PSP_MGR_RESULT: + if (numargs >= 5 && args[0] < 6) { + dbglog_printf(timestamp, vap_id, + "%s: %s, PsPollAvg(%u), EstimationOverrun(%u), EstimationUnderun(%u), NotReadyErr(%u)", + dbg_id_str, coex_pspoll_state[args[0]], + args[1], args[2], args[3], args[4]); + } else { + return false; + } + break; + case COEX_TRF_SHAPE_PSP: + if (numargs >= 5 && args[0] < 7 && args[1] < 7) { + dbglog_printf(timestamp, vap_id, + "%s: %s, %s, Dur(%u), BtTriggerRecvd(%u), PspWlanCritical(%u)", + dbg_id_str, coex_sched_type[args[0]], + wlan_weight[args[1]], args[2], args[3], + args[4]); + } else { + return false; + } + break; + case COEX_PSP_SPEC_POLL: + if (numargs >= 5) { + dbglog_printf(timestamp, vap_id, + "%s: PsPollSpecEna(%u), Count(%u), NextTS(%u), AllowSpecPsPollTx(%u), Intvl(%u)", + dbg_id_str, args[0], args[1], args[2], + args[3], args[4]); + } else { + return false; + } + break; + case COEX_PSP_READY_STATE: + if (numargs >= 5) { + dbglog_printf(timestamp, vap_id, + "%s: T2NonWlan(%u), CoexSchedulerEndTS(%u), MoreData(%u), PSPRespExpectedTS(%u), NonWlanIdleT(%u)", + dbg_id_str, args[0], args[1], args[2], + args[3], args[4]); + } else { + return false; + } + break; + case COEX_PSP_NONWLAN_INTERVAL: + if (numargs >= 4) { + dbglog_printf(timestamp, vap_id, + "%s: NonWlanBaseIntvl(%u), NonWlanIdleT(%u), PSPSpecIntvl(%u), ApRespTimeout(%u)", + dbg_id_str, args[0], args[1], args[2], + args[3]); + } else { + return false; + } + break; + case COEX_PSP_ERROR: + if (numargs >= 1 && args[0] < 9) { + dbglog_printf_no_line_break(timestamp, vap_id, "%s: %s", + dbg_id_str, + coex_psp_error_type[args + [0]]); + for (i = 1; i < numargs; i++) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, + (", %u", args[i])); + } + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("\n")); + } else { + return false; + } + break; + case COEX_PSP_STAT_1: + if (numargs >= 5) { + dbglog_printf(timestamp, vap_id, + "%s: ApResp0(%u), ApResp1(%u), ApResp2(%u), ApResp3(%u), ApResp4(%u)", + dbg_id_str, args[0], args[1], args[2], + args[3], args[4]); + } else { + return false; + } + break; + case COEX_PSP_STAT_2: + if (numargs >= 5) { + dbglog_printf(timestamp, vap_id, + "%s: DataPt(%u), Max(%u), NextApRespIndex(%u), NumOfValidDataPts(%u), PsPollAvg(%u)", + dbg_id_str, args[0], args[1], args[2], + args[3], args[4]); + } else { + return false; + } + break; + case COEX_PSP_RX_STATUS_STATE_1: + if (numargs >= 5) { + if (args[2]) { + dbglog_printf(timestamp, vap_id, + "%s: RsExpectedTS(%u), RespActualTS(%u), Overrun, RsOverrunT(%u), RsRxDur(%u)", + dbg_id_str, args[0], args[1], + args[3], args[4]); + } else { + dbglog_printf(timestamp, vap_id, + "%s: RsExpectedTS(%u), RespActualTS(%u), Underrun, RsUnderrunT(%u), RsRxDur(%u)", + dbg_id_str, args[0], args[1], + args[3], args[4]); + } + } else { + return false; + } + break; + default: + return false; + } + + return true; +} + +static A_BOOL +dbglog_beacon_print_handler(A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, A_UINT32 *args) +{ + static const char *states[] = { + "INIT", + "ADJUST_START", + "ADJUSTING", + "ADJUST_HOLD", + }; + + static const char *events[] = { + "ADJUST_START", + "ADJUST_RESTART", + "ADJUST_STOP", + "ADJUST_PAUSE", + "ADJUST_UNPAUSE", + "ADJUST_INC_SLOP_STEP", + "ADJUST_HOLD", + "ADJUST_HOLD_TIME_OUT", + }; + + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "EARLY_RX", + states, QDF_ARRAY_SIZE(states), events, + QDF_ARRAY_SIZE(events)); + break; + case BEACON_EVENT_EARLY_RX_BMISS_STATUS: + if (numargs == 3) { + dbglog_printf(timestamp, vap_id, + "early_rx bmiss status:rcv=%d total=%d miss=%d", + args[0], args[1], args[2]); + } + break; + case BEACON_EVENT_EARLY_RX_SLEEP_SLOP: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "early_rx update sleep_slop:%d", args[0]); + } + break; + case BEACON_EVENT_EARLY_RX_CONT_BMISS_TIMEOUT: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "early_rx cont bmiss timeout,update sleep_slop:%d", + args[0]); + } + break; + case BEACON_EVENT_EARLY_RX_PAUSE_SKIP_BCN_NUM: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "early_rx skip bcn num:%d", args[0]); + } + break; + case BEACON_EVENT_EARLY_RX_CLK_DRIFT: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "early_rx clk drift:%d", args[0]); + } + break; + case BEACON_EVENT_EARLY_RX_AP_DRIFT: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "early_rx ap drift:%d", args[0]); + } + break; + case BEACON_EVENT_EARLY_RX_BCN_TYPE: + if (numargs == 1) { + dbglog_printf(timestamp, vap_id, + "early_rx bcn type:%d", args[0]); + } + break; + default: + return false; + } + + return true; +} + +static A_BOOL +dbglog_data_txrx_print_handler(A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, A_UINT32 *args) +{ + switch (dbg_id) { + case DATA_TXRX_DBGID_RX_DATA_SEQ_LEN_INFO: + dbglog_printf(timestamp, vap_id, + "DATA RX seq=0x%x, len=0x%x, stored=0x%x, duperr=0x%x", + args[0], args[1], (args[2] & 0xffff0000) >> 16, + args[2] & 0x0000ffff); + break; + default: + return false; + } + + return true; +} + +static +A_BOOL dbglog_smps_print_handler(A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, A_UINT32 *args) +{ + static const char *states[] = { + "S_INACTIVE", + "S_STATIC", + "S_DYNAMIC", + "S_STALLED", + "S_INACTIVE_WAIT", + "S_STATIC_WAIT", + "S_DYNAMIC_WAIT", + }; + + static const char *events[] = { + "E_STOP", + "E_STOP_COMPL", + "E_START", + "E_STATIC", + "E_STATIC_COMPL", + "E_DYNAMIC", + "E_DYNAMIC_COMPL", + "E_STALL", + "E_RSSI_ABOVE_THRESH", + "E_RSSI_BELOW_THRESH", + "E_FORCED_NONE", + }; + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "STA_SMPS SM", + states, QDF_ARRAY_SIZE(states), events, + QDF_ARRAY_SIZE(events)); + break; + case STA_SMPS_DBGID_CREATE_PDEV_INSTANCE: + dbglog_printf(timestamp, vap_id, "STA_SMPS Create PDEV ctx %#x", + args[0]); + break; + case STA_SMPS_DBGID_CREATE_VIRTUAL_CHAN_INSTANCE: + dbglog_printf(timestamp, vap_id, + "STA_SMPS Create Virtual Chan ctx %#x", args[0]); + break; + case STA_SMPS_DBGID_DELETE_VIRTUAL_CHAN_INSTANCE: + dbglog_printf(timestamp, vap_id, + "STA_SMPS Delete Virtual Chan ctx %#x", args[0]); + break; + case STA_SMPS_DBGID_CREATE_STA_INSTANCE: + dbglog_printf(timestamp, vap_id, "STA_SMPS Create STA ctx %#x", + args[0]); + break; + case STA_SMPS_DBGID_DELETE_STA_INSTANCE: + dbglog_printf(timestamp, vap_id, "STA_SMPS Delete STA ctx %#x", + args[0]); + break; + case STA_SMPS_DBGID_VIRTUAL_CHAN_SMPS_START: + break; + case STA_SMPS_DBGID_VIRTUAL_CHAN_SMPS_STOP: + break; + case STA_SMPS_DBGID_SEND_SMPS_ACTION_FRAME: + dbglog_printf(timestamp, vap_id, + "STA_SMPS STA %#x Signal SMPS mode as %s; cb_flags %#x", + args[0], + (args[1] == + 0 ? "DISABLED" : (args[1] == + 0x1 ? "STATIC" : (args[1] == + 0x3 ? + "DYNAMIC" : + "UNKNOWN"))), + args[2]); + break; + case STA_SMPS_DBGID_DTIM_EBT_EVENT_CHMASK_UPDATE: + dbglog_printf(timestamp, vap_id, + "STA_SMPS_DBGID_DTIM_EBT_EVENT_CHMASK_UPDATE"); + break; + case STA_SMPS_DBGID_DTIM_CHMASK_UPDATE: + dbglog_printf(timestamp, vap_id, + "STA_SMPS_DBGID_DTIM_CHMASK_UPDATE " + "tx_mask %#x rx_mask %#x arb_dtim_mask %#x", + args[0], args[1], args[2]); + break; + case STA_SMPS_DBGID_DTIM_BEACON_EVENT_CHMASK_UPDATE: + dbglog_printf(timestamp, vap_id, + "STA_SMPS_DBGID_DTIM_BEACON_EVENT_CHMASK_UPDATE"); + break; + case STA_SMPS_DBGID_DTIM_POWER_STATE_CHANGE: + dbglog_printf(timestamp, vap_id, + "STA_SMPS_DBGID_DTIM_POWER_STATE_CHANGE cur_pwr_state %s new_pwr_state %s", + (args[0] == + 0x1 ? "SLEEP" : (args[0] == + 0x2 ? "AWAKE" : (args[0] == + 0x3 ? + "FULL_SLEEP" : + "UNKNOWN"))), + (args[1] == + 0x1 ? "SLEEP" : (args[1] == + 0x2 ? "AWAKE" : (args[1] == + 0x3 ? + "FULL_SLEEP" : + "UNKNOWN")))); + break; + case STA_SMPS_DBGID_DTIM_CHMASK_UPDATE_SLEEP: + dbglog_printf(timestamp, vap_id, + "STA_SMPS_DBGID_DTIM_CHMASK_UPDATE_SLEEP " + "tx_mask %#x rx_mask %#x orig_rx %#x dtim_rx %#x", + args[0], args[1], args[2], args[3]); + break; + case STA_SMPS_DBGID_DTIM_CHMASK_UPDATE_AWAKE: + dbglog_printf(timestamp, vap_id, + "STA_SMPS_DBGID_DTIM_CHMASK_UPDATE_AWAKE " + "tx_mask %#x rx_mask %#x orig_rx %#x", args[0], + args[1], args[2]); + break; + default: + dbglog_printf(timestamp, vap_id, "STA_SMPS: UNKNOWN DBGID!"); + return false; + } + + return true; +} + +static A_BOOL +dbglog_p2p_print_handler(A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, A_UINT16 numargs, A_UINT32 *args) +{ + static const char *states[] = { + "ACTIVE", + "DOZE", + "TX_BCN", + "CTWIN", + "OPPPS", + }; + + static const char *events[] = { + "ONESHOT_NOA", + "CTWINDOW", + "PERIODIC_NOA", + "IDLE", + "NOA_CHANGED", + "TBTT", + "TX_BCN_CMP", + "OPPPS_OK", + "OPPPS_CHANGED", + }; + + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "P2P GO PS", + states, QDF_ARRAY_SIZE(states), events, + QDF_ARRAY_SIZE(events)); + break; + default: + return false; + } + + return true; +} + +static A_BOOL +dbglog_pcielp_print_handler(A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, + A_UINT16 numargs, A_UINT32 *args) +{ + static const char *states[] = { + "STOP", + "TX", + "RX", + "SLEEP", + "SUSPEND", + }; + + static const char *events[] = { + "VDEV_UP", + "ALL_VDEV_DOWN", + "AWAKE", + "SLEEP", + "TX_ACTIVITY", + "TX_INACTIVITY", + "TX_AC_CHANGE", + "SUSPEND", + "RESUME", + }; + + switch (dbg_id) { + case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG: + dbglog_sm_print(timestamp, vap_id, numargs, args, "PCIELP", + states, QDF_ARRAY_SIZE(states), events, + QDF_ARRAY_SIZE(events)); + break; + default: + return false; + } + + return true; +} + +#ifdef WLAN_OPEN_SOURCE +static int dbglog_block_open(struct inode *inode, struct file *file) +{ + struct fwdebug *fwlog = inode->i_private; + + if (fwlog->fwlog_open) + return -EBUSY; + + fwlog->fwlog_open = true; + + file->private_data = inode->i_private; + return 0; +} + +static int dbglog_block_release(struct inode *inode, struct file *file) +{ + struct fwdebug *fwlog = inode->i_private; + + fwlog->fwlog_open = false; + + return 0; +} + +static ssize_t dbglog_block_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct fwdebug *fwlog = file->private_data; + struct sk_buff *skb; + ssize_t ret_cnt; + size_t len = 0, not_copied; + char *buf; + int ret; + + buf = vmalloc(count); + if (!buf) + return -ENOMEM; + + spin_lock_bh(&fwlog->fwlog_queue.lock); + + if (skb_queue_len(&fwlog->fwlog_queue) == 0) { + /* we must init under queue lock */ + init_completion(&fwlog->fwlog_completion); + + spin_unlock_bh(&fwlog->fwlog_queue.lock); + + ret = + wait_for_completion_interruptible(&fwlog->fwlog_completion); + if (ret == -ERESTARTSYS) { + vfree(buf); + return ret; + } + + spin_lock_bh(&fwlog->fwlog_queue.lock); + } + + while ((skb = __skb_dequeue(&fwlog->fwlog_queue))) { + if (skb->len > count - len) { + /* not enough space, put skb back and leave */ + __skb_queue_head(&fwlog->fwlog_queue, skb); + break; + } + + memcpy(buf + len, skb->data, skb->len); + len += skb->len; + + kfree_skb(skb); + } + + spin_unlock_bh(&fwlog->fwlog_queue.lock); + + /* FIXME: what to do if len == 0? */ + not_copied = copy_to_user(user_buf, buf, len); + if (not_copied != 0) { + ret_cnt = -EFAULT; + goto out; + } + + *ppos = *ppos + len; + + ret_cnt = len; + +out: + vfree(buf); + + return ret_cnt; +} + +static const struct file_operations fops_dbglog_block = { + .open = dbglog_block_open, + .release = dbglog_block_release, + .read = dbglog_block_read, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +static int dbglog_debugfs_init(wmi_unified_t wmi_handle) +{ + + wmi_handle->debugfs_phy = debugfs_create_dir(CLD_DEBUGFS_DIR, NULL); + if (!wmi_handle->debugfs_phy) + return -ENOMEM; + + debugfs_create_file(DEBUGFS_BLOCK_NAME, S_IRUSR, + wmi_handle->debugfs_phy, &wmi_handle->dbglog, + &fops_dbglog_block); + + return true; +} + +static int dbglog_debugfs_remove(wmi_unified_t wmi_handle) +{ + debugfs_remove_recursive(wmi_handle->debugfs_phy); + return true; +} +#endif /* WLAN_OPEN_SOURCE */ + +/**--------------------------------------------------------------------------- + \brief cnss_diag_msg_callback() - Call back invoked by netlink service + + This function gets invoked by netlink service when a message is recevied + from the cnss-diag application in user-space. + + \param - + - skb - skb with netlink message + + \return - 0 for success, non zero for failure + --------------------------------------------------------------------------*/ +static int cnss_diag_msg_callback(struct sk_buff *skb) +{ + struct nlmsghdr *nlh; + struct dbglog_slot *slot; + A_UINT8 *msg; + + nlh = (struct nlmsghdr *)skb->data; + if (!nlh) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("%s: Netlink header null \n", __func__)); + return -EINVAL; + } + + msg = NLMSG_DATA(nlh); + + slot = (struct dbglog_slot *)msg; + switch (slot->diag_type) { + case DIAG_TYPE_CRASH_INJECT: + if (slot->length == 2) { + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, + ("%s : DIAG_TYPE_CRASH_INJECT: %d %d\n", + __func__, slot->payload[0], slot->payload[1])); + wma_cli_set2_command(0, GEN_PARAM_CRASH_INJECT, + slot->payload[0], slot->payload[1], + GEN_CMD); + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("crash_inject cmd error\n")); + } + break; + default: + break; + } + return 0; + +} + +/**--------------------------------------------------------------------------- + \brief cnss_diag_activate_service() - Activate cnss_diag message handler + + This function registers a handler to receive netlink message from + an cnss-diag application process. + + \param - + - None + + \return - 0 for success, non zero for failure + --------------------------------------------------------------------------*/ +int cnss_diag_activate_service(void) +{ + int ret = 0; + + /* Register the msg handler for msgs addressed to WLAN_NL_MSG_OEM */ + ret = nl_srv_register(WLAN_NL_MSG_CNSS_DIAG, cnss_diag_msg_callback); + if (ret) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("CNSS-DIAG Registration failed")); + return ret; + } + return 0; +} + +static A_BOOL +dbglog_wow_print_handler(A_UINT32 mod_id, + A_UINT16 vap_id, + A_UINT32 dbg_id, + A_UINT32 timestamp, A_UINT16 numargs, A_UINT32 *args) +{ + + switch (dbg_id) { + case WOW_NS_OFLD_ENABLE: + if (4 == numargs) { + dbglog_printf(timestamp, vap_id, + "Enable NS offload, for sender %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", + *(A_UINT8 *) &args[0], + *((A_UINT8 *) &args[0] + 1), + *((A_UINT8 *) &args[0] + 2), + *((A_UINT8 *) &args[0] + 3), + *(A_UINT8 *) &args[1], + *((A_UINT8 *) &args[1] + 1), + *((A_UINT8 *) &args[1] + 2), + *((A_UINT8 *) &args[1] + 3), + *(A_UINT8 *) &args[2], + *((A_UINT8 *) &args[2] + 1), + *((A_UINT8 *) &args[2] + 2), + *((A_UINT8 *) &args[2] + 3), + *(A_UINT8 *) &args[3], + *((A_UINT8 *) &args[3] + 1), + *((A_UINT8 *) &args[3] + 2), + *((A_UINT8 *) &args[3] + 3)); + } else { + return false; + } + break; + case WOW_ARP_OFLD_ENABLE: + if (1 == numargs) { + dbglog_printf(timestamp, vap_id, + "Enable ARP offload, for sender %d.%d.%d.%d", + *(A_UINT8 *) args, + *((A_UINT8 *) args + 1), + *((A_UINT8 *) args + 2), + *((A_UINT8 *) args + 3)); + } else { + return false; + } + break; + case WOW_NS_ARP_OFLD_DISABLE: + if (0 == numargs) { + dbglog_printf(timestamp, vap_id, + "disable NS/ARP offload"); + } else { + return false; + } + break; + case WOW_NS_RECEIVED: + if (4 == numargs) { + dbglog_printf(timestamp, vap_id, + "NS requested from %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", + *(A_UINT8 *) &args[0], + *((A_UINT8 *) &args[0] + 1), + *((A_UINT8 *) &args[0] + 2), + *((A_UINT8 *) &args[0] + 3), + *(A_UINT8 *) &args[1], + *((A_UINT8 *) &args[1] + 1), + *((A_UINT8 *) &args[1] + 2), + *((A_UINT8 *) &args[1] + 3), + *(A_UINT8 *) &args[2], + *((A_UINT8 *) &args[2] + 1), + *((A_UINT8 *) &args[2] + 2), + *((A_UINT8 *) &args[2] + 3), + *(A_UINT8 *) &args[3], + *((A_UINT8 *) &args[3] + 1), + *((A_UINT8 *) &args[3] + 2), + *((A_UINT8 *) &args[3] + 3)); + } else { + return false; + } + break; + case WOW_NS_REPLIED: + if (4 == numargs) { + dbglog_printf(timestamp, vap_id, + "NS replied to %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", + *(A_UINT8 *) &args[0], + *((A_UINT8 *) &args[0] + 1), + *((A_UINT8 *) &args[0] + 2), + *((A_UINT8 *) &args[0] + 3), + *(A_UINT8 *) &args[1], + *((A_UINT8 *) &args[1] + 1), + *((A_UINT8 *) &args[1] + 2), + *((A_UINT8 *) &args[1] + 3), + *(A_UINT8 *) &args[2], + *((A_UINT8 *) &args[2] + 1), + *((A_UINT8 *) &args[2] + 2), + *((A_UINT8 *) &args[2] + 3), + *(A_UINT8 *) &args[3], + *((A_UINT8 *) &args[3] + 1), + *((A_UINT8 *) &args[3] + 2), + *((A_UINT8 *) &args[3] + 3)); + } else { + return false; + } + break; + case WOW_ARP_RECEIVED: + if (1 == numargs) { + dbglog_printf(timestamp, vap_id, + "ARP requested from %d.%d.%d.%d", + *(A_UINT8 *) args, + *((A_UINT8 *) args + 1), + *((A_UINT8 *) args + 2), + *((A_UINT8 *) args + 3)); + } else { + return false; + } + break; + break; + case WOW_ARP_REPLIED: + if (1 == numargs) { + dbglog_printf(timestamp, vap_id, + "ARP replied to %d.%d.%d.%d", + *(A_UINT8 *) args, + *((A_UINT8 *) args + 1), + *((A_UINT8 *) args + 2), + *((A_UINT8 *) args + 3)); + } else { + return false; + } + break; + default: + return false; + } + + return true; +} + +int dbglog_parser_type_init(wmi_unified_t wmi_handle, int type) +{ + if (type >= DBGLOG_PROCESS_MAX) { + return A_ERROR; + } + + dbglog_process_type = type; + gprint_limiter = false; + + return A_OK; +} + +int dbglog_init(wmi_unified_t wmi_handle) +{ + int res = 0; + OS_MEMSET(mod_print, 0, sizeof(mod_print)); + + dbglog_reg_modprint(WLAN_MODULE_STA_PWRSAVE, + dbglog_sta_powersave_print_handler); + dbglog_reg_modprint(WLAN_MODULE_AP_PWRSAVE, + dbglog_ap_powersave_print_handler); + dbglog_reg_modprint(WLAN_MODULE_WAL, dbglog_wal_print_handler); + dbglog_reg_modprint(WLAN_MODULE_SCAN, dbglog_scan_print_handler); + dbglog_reg_modprint(WLAN_MODULE_RATECTRL, + dbglog_ratectrl_print_handler); + dbglog_reg_modprint(WLAN_MODULE_ANI, dbglog_ani_print_handler); + dbglog_reg_modprint(WLAN_MODULE_COEX, dbglog_coex_print_handler); + dbglog_reg_modprint(WLAN_MODULE_BEACON, dbglog_beacon_print_handler); + dbglog_reg_modprint(WLAN_MODULE_WOW, dbglog_wow_print_handler); + dbglog_reg_modprint(WLAN_MODULE_DATA_TXRX, + dbglog_data_txrx_print_handler); + dbglog_reg_modprint(WLAN_MODULE_STA_SMPS, dbglog_smps_print_handler); + dbglog_reg_modprint(WLAN_MODULE_P2P, dbglog_p2p_print_handler); + dbglog_reg_modprint(WLAN_MODULE_PCIELP, dbglog_pcielp_print_handler); + dbglog_reg_modprint(WLAN_MODULE_IBSS_PWRSAVE, + dbglog_ibss_powersave_print_handler); + + /* Register handler for F3 or debug messages */ + res = + wmi_unified_register_event_handler(wmi_handle, + WMI_DEBUG_MESG_EVENTID, + dbglog_parse_debug_logs, + WMA_RX_WORK_CTX); + if (res != 0) + return res; + + /* Register handler for FW diag events */ + res = wmi_unified_register_event_handler(wmi_handle, + WMI_DIAG_DATA_CONTAINER_EVENTID, + fw_diag_data_event_handler, + WMA_RX_WORK_CTX); + if (res != 0) + return res; + + /* Register handler for new FW diag Event, LOG, MSG combined */ + res = wmi_unified_register_event_handler(wmi_handle, WMI_DIAG_EVENTID, + diag_fw_handler, + WMA_RX_WORK_CTX); + if (res != 0) + return res; + +#ifdef WLAN_OPEN_SOURCE + /* Initialize the fw debug log queue */ + skb_queue_head_init(&wmi_handle->dbglog.fwlog_queue); + init_completion(&wmi_handle->dbglog.fwlog_completion); + + /* Initialize debugfs */ + dbglog_debugfs_init(wmi_handle); +#endif /* WLAN_OPEN_SOURCE */ + + return res; +} + +int dbglog_deinit(wmi_unified_t wmi_handle) +{ + int res = 0; + +#ifdef WLAN_OPEN_SOURCE + /* DeInitialize the fw debug log queue */ + skb_queue_purge(&wmi_handle->dbglog.fwlog_queue); + complete(&wmi_handle->dbglog.fwlog_completion); + + /* Deinitialize the debugfs */ + dbglog_debugfs_remove(wmi_handle); +#endif /* WLAN_OPEN_SOURCE */ + + res = + wmi_unified_unregister_event_handler(wmi_handle, + WMI_DEBUG_MESG_EVENTID); + if (res != 0) + return res; + + return res; +} diff --git a/utils/fwlog/dbglog_host.h b/utils/fwlog/dbglog_host.h new file mode 100644 index 0000000000..2dda8d25c3 --- /dev/null +++ b/utils/fwlog/dbglog_host.h @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2011, 2014-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _DBGLOG_HOST_H_ +#define _DBGLOG_HOST_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "dbglog_common.h" +#include "ol_defines.h" + +#define DIAG_FWID_OFFSET 24 +#define DIAG_FWID_MASK 0xFF000000 /* Bit 24-31 */ + +#define DIAG_TIMESTAMP_OFFSET 0 +#define DIAG_TIMESTAMP_MASK 0x00FFFFFF /* Bit 0-23 */ + +#define DIAG_ID_OFFSET 16 +#define DIAG_ID_MASK 0xFFFF0000 /* Bit 16-31 */ + +#define DIAG_VDEVID_OFFSET 11 +#define DIAG_VDEVID_MASK 0x0000F800 /* Bit 11-15 */ +#define DIAG_VDEVID_NUM_MAX 16 + +#define DIAG_VDEVLEVEL_OFFSET 8 +#define DIAG_VDEVLEVEL_MASK 0x00000700 /* Bit 8-10 */ + +#define DIAG_PAYLEN_OFFSET 0 +#define DIAG_PAYLEN_MASK 0x000000FF /* Bit 0-7 */ + +#define DIAG_PAYLEN_OFFSET16 0 +#define DIAG_PAYLEN_MASK16 0x0000FFFF /* Bit 0-16 */ + +#define DIAG_GET_TYPE(arg) \ + ((arg & DIAG_FWID_MASK) >> DIAG_FWID_OFFSET) + +#define DIAG_GET_TIME_STAMP(arg) \ + ((arg & DIAG_TIMESTAMP_MASK) >> DIAG_TIMESTAMP_OFFSET) + +#define DIAG_GET_ID(arg) \ + ((arg & DIAG_ID_MASK) >> DIAG_ID_OFFSET) + +#define DIAG_GET_VDEVID(arg) \ + ((arg & DIAG_VDEVID_MASK) >> DIAG_VDEVID_OFFSET) + +#define DIAG_GET_VDEVLEVEL(arg) \ + ((arg & DIAG_VDEVLEVEL_MASK) >> DIAG_VDEVLEVEL_OFFSET) + +#define DIAG_GET_PAYLEN(arg) \ + ((arg & DIAG_PAYLEN_MASK) >> DIAG_PAYLEN_OFFSET) + +#define DIAG_GET_PAYLEN16(arg) \ + ((arg & DIAG_PAYLEN_MASK16) >> DIAG_PAYLEN_OFFSET16) + +/* + * set the dbglog parser type + */int +dbglog_parser_type_init(wmi_unified_t wmi_handle, int type); + +/** dbglog_int - Registers a WMI event handle for WMI_DBGMSG_EVENT + * @brief wmi_handle - handle to wmi module + */ +int +dbglog_init(wmi_unified_t wmi_handle); + +/** dbglog_deinit - UnRegisters a WMI event handle for WMI_DBGMSG_EVENT + * @brief wmi_handle - handle to wmi module + */ +int +dbglog_deinit(wmi_unified_t wmi_handle); + +/** set the size of the report size + * @brief wmi_handle - handle to Wmi module + * @brief size - Report size + */ +int +dbglog_set_report_size(wmi_unified_t wmi_handle, A_UINT16 size); + +/** Set the resolution for time stamp + * @brief wmi_handle - handle to Wmi module + * @ brief tsr - time stamp resolution + */ +int +dbglog_set_timestamp_resolution(wmi_unified_t wmi_handle, + A_UINT16 tsr); + +/** Enable reporting. If it is set to false then Traget wont deliver + * any debug information + */ +int +dbglog_report_enable(wmi_unified_t wmi_handle, A_BOOL isenable); + +/** Set the log level + * @brief DBGLOG_INFO - Information lowest log level + * @brief DBGLOG_WARNING + * @brief DBGLOG_ERROR - default log level + */ +int +dbglog_set_log_lvl(wmi_unified_t wmi_handle, enum DBGLOG_LOG_LVL log_lvl); + +/* + * set the debug log level for a given module + * mod_id_lvl : the format is more user friendly. + * module_id = mod_id_lvl/10; + * log_level = mod_id_lvl%10; + * example : mod_id_lvl is 153. then module id is 15 and log level is 3. this format allows + * user to pass a sinlge value (which is the most convenient way for most of the OSs) + * to be passed from user to the driver. + */ +int +dbglog_set_mod_log_lvl(wmi_unified_t wmi_handle, A_UINT32 mod_id_lvl); + +/** Enable/Disable the logging for VAP */ +int +dbglog_vap_log_enable(wmi_unified_t wmi_handle, A_UINT16 vap_id, + A_BOOL isenable); +/** Enable/Disable logging for Module */ +int +dbglog_module_log_enable(wmi_unified_t wmi_handle, A_UINT32 mod_id, + A_BOOL isenable); + +/** set vap enablie bitmap */ +void +dbglog_set_vap_enable_bitmap(wmi_unified_t wmi_handle, + A_UINT32 vap_enable_bitmap); + +/** set log level for all the modules specified in the bitmap. for all other modules + * with 0 in the bitmap (or) outside the bitmap , the log level be reset to DBGLOG_ERR. + */ +void +dbglog_set_mod_enable_bitmap(wmi_unified_t wmi_handle, + A_UINT32 log_level, + A_UINT32 *mod_enable_bitmap, + A_UINT32 bitmap_len); + +int +dbglog_parse_debug_logs(ol_scn_t scn, u_int8_t *datap, + u_int32_t len); + + +/** Register the cnss_diag activate with the wlan driver */ +int cnss_diag_activate_service(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _DBGLOG_HOST_H_ */ diff --git a/utils/host_diag_log/inc/host_diag_core_event.h b/utils/host_diag_log/inc/host_diag_core_event.h new file mode 100644 index 0000000000..89cb8263f8 --- /dev/null +++ b/utils/host_diag_log/inc/host_diag_core_event.h @@ -0,0 +1,453 @@ +/* + * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined(__HOST_DIAG_CORE_EVENT_H) +#define __HOST_DIAG_CORE_EVENT_H + +/**========================================================================= + + \file host_diag_core_event.h + + \brief WLAN UTIL host DIAG Events + + Definitions for DIAG Events + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "qdf_types.h" +#include "i_host_diag_core_event.h" + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define WAKE_LOCK_NAME_LEN 80 + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_SECURITY + ------------------------------------------------------------------------*/ +typedef struct { + uint8_t eventId; + uint8_t authMode; + uint8_t encryptionModeUnicast; + uint8_t encryptionModeMulticast; + uint8_t pmkIDMatch; + uint8_t bssid[6]; + uint8_t keyId; + uint8_t status; +} host_event_wlan_security_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_STATUS_V2 + ------------------------------------------------------------------------*/ +typedef struct { + uint8_t eventId; + uint8_t ssid[32]; + uint8_t bssType; + uint8_t rssi; + uint8_t channel; + uint8_t qosCapability; + uint8_t authType; + uint8_t encryptionType; + uint8_t reason; + uint8_t reasonDisconnect; +} host_event_wlan_status_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_HANDOFF + ------------------------------------------------------------------------*/ +typedef struct { + uint8_t eventId; + uint8_t currentApBssid[6]; + uint8_t currentApRssi; + uint8_t candidateApBssid[6]; + uint8_t candidateApRssi; +} host_event_wlan_handoff_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_VCC + ------------------------------------------------------------------------*/ +typedef struct { + uint8_t eventId; + uint8_t rssi; + uint8_t txPer; + uint8_t rxPer; + int linkQuality; +} host_event_wlan_vcc_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_QOS + ------------------------------------------------------------------------*/ +typedef struct { + uint8_t eventId; + uint8_t reasonCode; +} host_event_wlan_qos_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_PE + ------------------------------------------------------------------------*/ +typedef struct { + char bssid[6]; + uint16_t event_type; + uint16_t sme_state; + uint16_t mlm_state; + uint16_t status; + uint16_t reason_code; +} host_event_wlan_pe_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_ADD_BLOCK_ACK_SUCCESS + ------------------------------------------------------------------------*/ +typedef struct { + char ucBaPeerMac[6]; + uint8_t ucBaTid; + uint8_t ucBaBufferSize; + uint16_t usBaSSN; + uint8_t fInitiator; +} host_event_wlan_add_block_ack_success_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_ADD_BLOCK_ACK_FAILED + ------------------------------------------------------------------------*/ +typedef struct { + char ucBaPeerMac[6]; + uint8_t ucBaTid; + uint8_t ucReasonCode; + uint8_t fInitiator; +} host_event_wlan_add_block_ack_failed_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_DELETE_BLOCK_ACK_SUCCESS + ------------------------------------------------------------------------*/ +typedef struct { + char ucBaPeerMac[6]; + uint8_t ucBaTid; + uint8_t ucDeleteReasonCode; +} host_event_wlan_add_block_ack_deleted_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_DELETE_BLOCK_ACK_FAILED + ------------------------------------------------------------------------*/ +typedef struct { + char ucBaPeerMac[6]; + uint8_t ucBaTid; + uint8_t ucDeleteReasonCode; + uint8_t ucFailReasonCode; +} host_event_wlan_add_block_ack_delete_failed_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_BSS_PROTECTION + ------------------------------------------------------------------------*/ +typedef struct { + uint8_t event_type; + uint8_t prot_type; +} host_event_wlan_bss_prot_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_BRINGUP_STATUS + ------------------------------------------------------------------------*/ +typedef struct { + uint16_t wlanStatus; + char driverVersion[10]; +} host_event_wlan_bringup_status_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_POWERSAVE_WOW + ------------------------------------------------------------------------*/ +typedef struct { + uint8_t event_subtype; + uint8_t wow_type; + uint8_t wow_magic_pattern[6]; + uint8_t wow_del_ptrn_id; + uint8_t wow_wakeup_cause; + uint8_t wow_wakeup_cause_pbm_ptrn_id; +} host_event_wlan_powersave_wow_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_BTC + ------------------------------------------------------------------------*/ +typedef struct { + uint8_t eventId; + uint8_t btAddr[6]; + uint16_t connHandle; + uint8_t connStatus; + uint8_t linkType; + uint8_t scoInterval; + uint8_t scoWindow; + uint8_t retransWindow; + uint8_t mode; +} host_event_wlan_btc_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_EAPOL + ------------------------------------------------------------------------*/ +/** + * struct host_event_wlan_eapol - Structure holding the eapol information + * @event_sub_type: 0-Transmitted, 1-Received + * @eapol_packet_type: 0 - EAP Start, 1 - EAPOL Start, 2 - EAPOL Logoff + 3 - EAPOL Key, 4 - EAPOL Encapsulated Alert + * @eapol_key_info: This field from the driver is in big endian format. + * So, the masks .0x8013. can be used to extract the + * message type. After masking, the values corresponding + * to messages 1/2/3/4 are given below: + * Msg. 1 0x8000 + * Msg. 2 0x0001 + * Msg. 3 0x8013 + * Msg. 4 0x0003 + * @eapol_rate: Rate at which the frame is received + * @dest_addr: Destination address + * @src_addr: Source address + * + * This structure contains the EAPOL information related to logging + */ +struct host_event_wlan_eapol { + uint8_t event_sub_type; + uint8_t eapol_packet_type; + uint16_t eapol_key_info; + uint16_t eapol_rate; + uint8_t dest_addr[6]; + uint8_t src_addr[6]; +}; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_LOW_RESOURCE_FAILURE + ------------------------------------------------------------------------*/ +/** + * struct host_event_wlan_low_resource_failure - Structure holding the + * low resource failure information + * @event_sub_type: Gives further information about reason for + * low resource condition + * + * This structure will hold the low resource failure information + */ +struct host_event_wlan_low_resource_failure { + uint8_t event_sub_type; +}; + +/** + * enum resource_failure_type - Reason for low resource failure condition + * @WIFI_EVENT_MEMORY_FAILURE: Memory failure + * + * This enum has the reason codes why the low resource situation is observed + */ +enum resource_failure_type { + WIFI_EVENT_MEMORY_FAILURE, +}; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_WAKE_LOCK + ------------------------------------------------------------------------*/ +/** + * struct host_event_wlan_wake_lock - Structure holding the wakelock information + * @status: Whether the wakelock is taken/released + * @reason: Reason for taking this wakelock + * @timeout: Timeout value in case of timed wakelocks + * @name_len: Length of the name of the wakelock that will follow + * @name: Name of the wakelock + * + * This structure will hold the wakelock information + */ +struct host_event_wlan_wake_lock { + uint32_t status; + uint32_t reason; + uint32_t timeout; + uint32_t name_len; + char name[WAKE_LOCK_NAME_LEN]; +}; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_LOG_COMPLETE + ------------------------------------------------------------------------*/ +/** + * struct host_event_wlan_log_complete - Holds log completion details + * @is_fatal: Indicates if the event is fatal or not + * @indicator: Source of the bug report - Framework/Host/Firmware + * @reason_code: Reason for triggering bug report + * @reserved: Reserved field + * + * This structure holds the log completion related information + */ +struct host_event_wlan_log_complete { + uint32_t is_fatal; + uint32_t indicator; + uint32_t reason_code; + uint32_t reserved; +}; + +/** + * struct host_event_tdls_teardown - tdls teardown diag event + * @reason: reason for tear down + * @peer_mac: peer mac + * + * This structure contains tdls teardown diag event info + */ +struct host_event_tdls_teardown { + uint32_t reason; + uint8_t peer_mac[QDF_MAC_ADDR_SIZE]; +}; + +/** + * struct host_event_tdls_enable_link - tdls enable link event + * @peer_mac: peer mac + * @is_off_chan_supported: if off channel supported + * @is_off_chan_configured: if off channel configured + * @is_off_chan_established: if off channel established + * + * This structure contain tdls enable link diag event info + */ +struct host_event_tdls_enable_link { + uint8_t peer_mac[QDF_MAC_ADDR_SIZE]; + uint8_t is_off_chan_supported; + uint8_t is_off_chan_configured; + uint8_t is_off_chan_established; +}; + +/** + * struct host_event_suspend - suspend/resume state + * @state: suspend/resume state + * + * This structure contains suspend resume diag event info + */ +struct host_event_suspend { + uint8_t state; +}; + +/** + * struct host_event_offload_req - offload state + * @offload_type: offload type + * @state: enabled or disabled state + * + * This structure contains offload diag event info + */ +struct host_event_offload_req { + uint8_t offload_type; + uint8_t state; +}; + +/** + * struct host_event_tdls_scan_rejected - scan + * rejected due to tdls + * @status: rejected status + * + * This structure contains scan rejected due to + * tdls event info + */ +struct host_event_tdls_scan_rejected { + uint8_t status; +}; + +/** + * struct host_event_tdls_tx_rx_mgmt - for TX RX management frame + * @event_id: event ID + * @tx_rx: tx or rx + * @type: type of frame + * @action_sub_type: action frame type + * @peer_mac: peer mac + * + * This structure contains tdls TX RX management frame info + */ +struct host_event_tdls_tx_rx_mgmt { + uint8_t event_id; + uint8_t tx_rx; + uint8_t type; + uint8_t action_sub_type; + uint8_t peer_mac[QDF_MAC_ADDR_SIZE]; +}; + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ +/** + * enum wifi_connectivity_events - Enum containing EAPOL sub type + * @WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED: EAPOL transmitted + * @WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED: EAPOL received + * + * This enum contains the EAPOL subtype + */ +enum wifi_connectivity_events { + WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED, + WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED, +}; + +/** + * enum wake_lock_reason - Reason for taking/releasing wakelock + * @WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT: Driver initialization + * @WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT: Driver re-initialization + * @WIFI_POWER_EVENT_WAKELOCK_DRIVER_EXIT: Driver shutdown + * @WIFI_POWER_EVENT_WAKELOCK_SCAN: Scan request/response handling + * @WIFI_POWER_EVENT_WAKELOCK_EXT_SCAN: Extended scan request/response handling + * @WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN: Driver resume + * @WIFI_POWER_EVENT_WAKELOCK_ROC: Remain on channel request/response handling + * @WIFI_POWER_EVENT_WAKELOCK_AUTO_SUSPEND: Auto suspend related handling + * @WIFI_POWER_EVENT_WAKELOCK_IPA: IPA related handling + * @WIFI_POWER_EVENT_WAKELOCK_ADD_STA: Addition of STA + * @WIFI_POWER_EVENT_WAKELOCK_HOLD_RX: Wakelocks taken for receive + * @WIFI_POWER_EVENT_WAKELOCK_SAP: SoftAP related wakelocks + * @WIFI_POWER_EVENT_WAKELOCK_WOW: WoW feature related + * @WIFI_POWER_EVENT_WAKELOCK_PNO: PNO feature related + * @WIFI_POWER_EVENT_WAKELOCK_DEL_STA: Deletion of a station + * @WIFI_POWER_EVENT_WAKELOCK_DFS: DFS related wakelocks + * @WIFI_POWER_EVENT_WAKELOCK_WMI_CMD_RSP: Firmware response + * @WIFI_POWER_EVENT_WAKELOCK_MISC: Miscellaneous wakelocks + * @WIFI_POWER_EVENT_WAKELOCK_DHCP: DHCP negotiation under way + * + * Indicates the reason for which the wakelock was taken/released + */ +enum wake_lock_reason { + WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT, + WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT, + WIFI_POWER_EVENT_WAKELOCK_DRIVER_EXIT, + WIFI_POWER_EVENT_WAKELOCK_SCAN, + WIFI_POWER_EVENT_WAKELOCK_EXT_SCAN, + WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN, + WIFI_POWER_EVENT_WAKELOCK_ROC, + WIFI_POWER_EVENT_WAKELOCK_AUTO_SUSPEND, + WIFI_POWER_EVENT_WAKELOCK_IPA, + WIFI_POWER_EVENT_WAKELOCK_ADD_STA, + WIFI_POWER_EVENT_WAKELOCK_HOLD_RX, + WIFI_POWER_EVENT_WAKELOCK_SAP, + WIFI_POWER_EVENT_WAKELOCK_WOW, + WIFI_POWER_EVENT_WAKELOCK_PNO, + WIFI_POWER_EVENT_WAKELOCK_DEL_STA, + WIFI_POWER_EVENT_WAKELOCK_DFS, + WIFI_POWER_EVENT_WAKELOCK_WMI_CMD_RSP, + WIFI_POWER_EVENT_WAKELOCK_MISC, + WIFI_POWER_EVENT_WAKELOCK_DHCP, +}; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __HOST_DIAG_CORE_EVENT_H */ diff --git a/utils/host_diag_log/inc/host_diag_core_log.h b/utils/host_diag_log/inc/host_diag_core_log.h new file mode 100644 index 0000000000..dbbfc11eab --- /dev/null +++ b/utils/host_diag_log/inc/host_diag_core_log.h @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined(__HOST_DIAG_CORE_LOG_H) +#define __HOST_DIAG_CORE_LOG_H + +/**========================================================================= + + \file host_diag_core_log.h + + \brief WLAN UTIL host DIAG logs + + Definitions for WLAN UTIL host diag events + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "qdf_types.h" +#include "i_host_diag_core_log.h" + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +#define HOST_LOG_MAX_NUM_SSID (21) +#define HOST_LOG_MAX_NUM_BSSID (21) +#define HOST_LOG_MAX_SSID_SIZE (32) +#define HOST_LOG_MAX_BSSID_SIZE (6) +#define HOST_LOG_MAX_NUM_CHANNEL (64) +#define HOST_LOG_MAX_NUM_HO_CANDIDATE_APS (20) +#define HOST_LOG_MAX_WOW_PTRN_SIZE (128) +#define HOST_LOG_MAX_WOW_PTRN_MASK_SIZE (16) +#define VOS_LOG_PKT_LOG_SIZE (2048) +#define HOST_LOG_PKT_LOG_THRESHOLD 40960 + +/* Version to be updated whenever format of vos_log_pktlog_info changes */ +#define VERSION_LOG_WLAN_PKT_LOG_INFO_C 1 + +/*--------------------------------------------------------------------------- + This packet contains the scan results of the recent scan operation + LOG_WLAN_SCAN_C 0x1496 + ---------------------------------------------------------------------------*/ +typedef struct { + log_hdr_type hdr; + uint8_t eventId; + uint8_t numSsid; + uint8_t ssid[HOST_LOG_MAX_NUM_SSID][HOST_LOG_MAX_SSID_SIZE]; + uint8_t bssid[HOST_LOG_MAX_NUM_BSSID][HOST_LOG_MAX_BSSID_SIZE]; + uint8_t totalSsid; + uint8_t minChnTime; + uint8_t maxChnTime; + uint16_t timeBetweenBgScan; + uint8_t BSSMode; + uint8_t numChannel; + uint8_t channels[HOST_LOG_MAX_NUM_CHANNEL]; + uint16_t status; +} host_log_scan_pkt_type; + +/*--------------------------------------------------------------------------- + This packet contains the information related to IBSS connection setup + LOG_WLAN_IBSS_C 0x1497 + ---------------------------------------------------------------------------*/ +typedef struct { + log_hdr_type hdr; + uint8_t eventId; + uint8_t channelSetting; + struct qdf_mac_addr bssid; + struct qdf_mac_addr peer_macaddr; + uint8_t ssid[HOST_LOG_MAX_SSID_SIZE]; + uint8_t operatingChannel; + uint8_t beaconInterval; + uint8_t status; +} host_log_ibss_pkt_type; + +/*--------------------------------------------------------------------------- + This packet contains the information related to 802.11D + LOG_WLAN_80211D_C 0x1498 + ---------------------------------------------------------------------------*/ +typedef struct { + log_hdr_type hdr; + uint8_t eventId; + uint8_t numChannel; + uint8_t Channels[HOST_LOG_MAX_NUM_CHANNEL]; + uint8_t TxPwr[HOST_LOG_MAX_NUM_CHANNEL]; + uint8_t countryCode[3]; + uint8_t supportMultipleDomain; +} host_log_802_11d_pkt_type; + +/*--------------------------------------------------------------------------- + This is a log packet which contains below handoff information: + - Current AP + RSSI (if already associated) + - Candidate AP + RSSI (before association and when the list is updated) + - For each BSSID in candidate list, provide RSSI, QoS and security compatibility + LOG_WLAN_HANDOFF_C 0x1499 + ---------------------------------------------------------------------------*/ +typedef struct { + uint8_t ssid[9]; + uint8_t bssid[HOST_LOG_MAX_BSSID_SIZE]; + uint8_t channel_id; + uint32_t qos_score; + uint32_t sec_score; + uint32_t rssi_score; + uint32_t overall_score; + uint32_t tx_per; /* represented as a % */ + uint32_t rx_per; /* represented as a % */ + +} host_log_ho_ap_info; + +typedef struct { + log_hdr_type hdr; + uint32_t num_aps; + host_log_ho_ap_info current_ap_info; + host_log_ho_ap_info + candidate_ap_info[HOST_LOG_MAX_NUM_HO_CANDIDATE_APS]; +} host_log_ho_pkt_type; + +/*--------------------------------------------------------------------------- + This packet contains the information related to the EDCA parameters + advertised by the AP + LOG_WLAN_QOS_EDCA_C 0x149A + ---------------------------------------------------------------------------*/ +typedef struct { + log_hdr_type hdr; + uint8_t aci_be; + uint8_t cw_be; + uint16_t txoplimit_be; + uint8_t aci_bk; + uint8_t cw_bk; + uint16_t txoplimit_bk; + uint8_t aci_vi; + uint8_t cw_vi; + uint16_t txoplimit_vi; + uint8_t aci_vo; + uint8_t cw_vo; + uint16_t txoplimit_vo; +} host_log_qos_edca_pkt_type; + +/*--------------------------------------------------------------------------- + This packet contains the total number of beacon received value + LOG_WLAN_BEACON_UPDATE_C 0x149B + ---------------------------------------------------------------------------*/ +typedef struct { + log_hdr_type hdr; + uint32_t bcn_rx_cnt; +} host_log_beacon_update_pkt_type; + +/*--------------------------------------------------------------------------- + This packet contains the information related to a WoW patern value when set + LOG_WLAN_POWERSAVE_WOW_ADD_PTRN_C 0x149C + ---------------------------------------------------------------------------*/ +typedef struct { + log_hdr_type hdr; + uint8_t pattern_id; + uint8_t pattern_byte_offset; + uint8_t pattern_size; + uint8_t pattern[HOST_LOG_MAX_WOW_PTRN_SIZE]; + uint8_t pattern_mask_size; + uint8_t pattern_mask[HOST_LOG_MAX_WOW_PTRN_MASK_SIZE]; +} host_log_powersave_wow_add_ptrn_pkt_type; + +/*--------------------------------------------------------------------------- + This packet contains the Tspec info negotiated with the AP for the + specific AC + LOG_WLAN_QOS_TSPEC_C 0x14A2 + ---------------------------------------------------------------------------*/ +typedef struct { + log_hdr_type hdr; + uint8_t tsinfo[3]; + uint16_t nominal_msdu_size; + uint16_t maximum_msdu_size; + uint32_t min_service_interval; + uint32_t max_service_interval; + uint32_t inactivity_interval; + uint32_t suspension_interval; + uint32_t svc_start_time; + uint32_t min_data_rate; + uint32_t mean_data_rate; + uint32_t peak_data_rate; + uint32_t max_burst_size; + uint32_t delay_bound; + uint32_t min_phy_rate; + uint16_t surplus_bw_allowance; + uint16_t medium_time; +} host_log_qos_tspec_pkt_type; + +/*--------------------------------------------------------------------------- + This packet contains data information when stall detected + LOG_TRSP_DATA_STALL_C 0x1801 + ---------------------------------------------------------------------------*/ + +typedef struct { + char channelName[4]; + uint32_t numDesc; + uint32_t numFreeDesc; + uint32_t numRsvdDesc; + uint32_t headDescOrder; + uint32_t tailDescOrder; + uint32_t ctrlRegVal; + uint32_t statRegVal; + uint32_t numValDesc; + uint32_t numInvalDesc; +} host_log_data_stall_channel_type; + +typedef struct { + log_hdr_type hdr; + uint32_t PowerState; + uint32_t numFreeBd; + host_log_data_stall_channel_type dxeChannelInfo[4]; +} host_log_data_stall_type; + +/*--------------------------------------------------------------------------- + This packet contains the rssi value from BSS descriptor + LOG_WLAN_RSSI_UPDATE_C 0x1354 + ---------------------------------------------------------------------------*/ +typedef struct { + log_hdr_type hdr; + int8_t rssi; +} host_log_rssi_pkt_type; + +/** + * struct host_log_pktlog_info - Packet log info + * @log_hdr: Log header + * @buf_len: Length of the buffer that follows + * @buf: Buffer containing the packet log info + * + * Structure containing the packet log information + * LOG_WLAN_PKT_LOG_INFO_C 0x18E0 + */ +struct host_log_pktlog_info { + log_hdr_type log_hdr; + uint32_t version; + uint32_t seq_no; + uint32_t buf_len; + uint8_t buf[]; +}; + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __HOST_DIAG_CORE_LOG_H */ diff --git a/utils/host_diag_log/inc/host_diag_event_defs.h b/utils/host_diag_log/inc/host_diag_event_defs.h new file mode 100644 index 0000000000..ff423bb48d --- /dev/null +++ b/utils/host_diag_log/inc/host_diag_event_defs.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef EVENT_DEFS_H +#define EVENT_DEFS_H + +typedef enum { + EVENT_DROP_ID = 0, + + /* Events between 0x1 to 0x674 are not used */ + + EVENT_WLAN_SECURITY = 0x675, /* 13 byte payload */ + EVENT_WLAN_STATUS, /* 15 byte payload */ + + /* Events 0x677 and 0x678 are not used */ + + EVENT_WLAN_QOS = 0x679, /* 2 byte payload */ + EVENT_WLAN_PE, /* 16 byte payload */ + + /* Events between 0x67b to 0x67f are not used */ + + EVENT_WLAN_BRINGUP_STATUS = 0x680, /* 12 byte payload */ + EVENT_WLAN_POWERSAVE_GENERIC, /* 16 byte payload */ + EVENT_WLAN_POWERSAVE_WOW, /* 11 byte payload */ + + /* Events between 0x683 to 0x690 are not used */ + + EVENT_WLAN_BTC = 0x691, /* 15 byte payload */ + EVENT_WLAN_EAPOL = 0xA8D,/* 18 bytes payload */ + EVENT_WLAN_WAKE_LOCK = 0xAA2, /* 96 bytes payload */ + EVENT_WLAN_BEACON_RECEIVED = 0xAA6, /* FW event: 2726 */ + EVENT_WLAN_LOG_COMPLETE = 0xAA7, /* 16 bytes payload */ + EVENT_WLAN_STATUS_V2 = 0xAB3, + + /* + * + * EVENT_WLAN_TDLS_TEARDOWN + * @ reason: reason for tear down. + * @peer_mac: Peer mac address + * + * + * This event is sent when TDLS tear down happens. + * + * Supported Feature: TDLS + * + * + */ + EVENT_WLAN_TDLS_TEARDOWN = 0xAB5, + + /* + * + * EVENT_WLAN_TDLS_ENABLE_LINK + * @peer_mac: peer mac + * @is_off_chan_supported: If peer supports off channel + * @is_off_chan_configured: If off channel is configured + * @is_off_chan_established: If off channel is established + * + * + * This event is sent when TDLS enable link happens. + * + * Supported Feature: TDLS + * + * + */ + EVENT_WLAN_TDLS_ENABLE_LINK = 0XAB6, + EVENT_WLAN_SUSPEND_RESUME = 0xAB7, + EVENT_WLAN_OFFLOAD_REQ = 0xAB8, + + /* + * + * EVENT_TDLS_SCAN_BLOCK + * @status: rejected status + * + * + * This event is sent when scan is rejected due to TDLS. + * + * Supported Feature: TDLS + * + * + */ + EVENT_TDLS_SCAN_BLOCK = 0xAB9, + + /* + * + * EVENT_WLAN_TDLS_TX_RX_MGMT + * @event_id: event id + * @tx_rx: tx or rx + * @type: type of frame + * @action_sub_type: action frame type + * @peer_mac: peer mac + * + * + * This event is sent when TDLS mgmt rx tx happens. + * + * Supported Feature: TDLS + * + * + */ + EVENT_WLAN_TDLS_TX_RX_MGMT = 0xABA, + EVENT_WLAN_LOW_RESOURCE_FAILURE = 0xABB, + + EVENT_MAX_ID = 0x0FFF +} event_id_enum_type; + +#endif /* EVENT_DEFS_H */ diff --git a/utils/host_diag_log/inc/log_codes.h b/utils/host_diag_log/inc/log_codes.h new file mode 100644 index 0000000000..65a843953e --- /dev/null +++ b/utils/host_diag_log/inc/log_codes.h @@ -0,0 +1,2075 @@ +/* + * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef LOG_CODES_H +#define LOG_CODES_H + +/*=========================================================================== + + Log Code Definitions + + General Description + This file contains log code definitions and is shared with the tools. + + ===========================================================================*/ + +/* DO NOT MODIFY THIS FILE WITHOUT PRIOR APPROVAL +** +** Log codes, by design, are a tightly controlled set of values. +** Developers may not create log codes at will. +** +** Request new logs using the following process: +** +** 1. Send email to asw.diag.request requesting log codassignments. +** 2. Identify the log needed by name. +** 3. Provide a brief description for the log. +** +*/ + +/*=========================================================================== + + Edit History + + $Header: //source/qcom/qct/core/services/diag/api/inc/main/latest/log_codes.h#9 $ + + when who what, where, why + -------- --- ---------------------------------------------------------- + 07/30/09 dhao Consolidate log_codes_apps.h + 07/30/09 dhao Add Last log code definition for Equip ID 11 + 06/26/09 dhao Update format the macro + 06/24/09 sar Reverted last change. + 06/24/09 sar Added log code for LOG_MC_STM_C. + 11/02/01 sfh Featurize common NAS log codes for UMTS. + 10/30/01 sfh Added log code for LOG_GPS_FATPATH_INFO_C. + 10/24/01 sfh Added updates for UMTS equipment ID and log codes. + 06/27/01 lad Added multiple equipment ID support. + 05/22/01 sfh Reserved log codes 158 - 168. + 05/21/01 sfh Keep confusing XXX_BASE_C names for backwards compatibility. + 05/16/01 sfh Reserved log code 155. + 05/08/01 sfh Reserved log codes 150 - 154. + 04/06/01 lad Added definitions of base IDs (such as LOG_WCDMA_BASE_C). + This is currently using temporary ID values in the 0x1000 + range. + 02/23/01 lad Created file from DMSS log.h. Log codes only + + ===========================================================================*/ +#include + +/* ------------------------------------------------------------------------- + * Data Declarations + * ------------------------------------------------------------------------- */ + +/* ------------------------------------------------------------------------- + * Log equipment IDs. + * The most significant 4 bits of the 16 bit log code is the equipment ID. + * Orignally, the mobile was to have an ID, and base stations and other + * IDs. As QCT technology diversifies, new equipment IDs are assigned to new + * technology areas. 0x2000 and 0x3000 are reserved for legacy reasons, so + * the first + * addition starts at 0x4000. + * ------------------------------------------------------------------------- */ + +#define LOG_1X_BASE_C ((uint16_t) 0x1000) +#define LOG_WCDMA_BASE_C ((uint16_t) 0x4000) +#define LOG_GSM_BASE_C ((uint16_t) 0x5000) +#define LOG_LBS_BASE_C ((uint16_t) 0x6000) +#define LOG_UMTS_BASE_C ((uint16_t) 0x7000) +#define LOG_TDMA_BASE_C ((uint16_t) 0x8000) +#define LOG_DTV_BASE_C ((uint16_t) 0xA000) +#define LOG_APPS_BASE_C ((uint16_t) 0xB000) +#define LOG_LTE_BASE_C ((uint16_t) (0xB000 + 0x0010)) +#define LOG_LTE_LAST_C ((uint16_t) 0xB1FF) +#define LOG_WIMAX_BASE_C ((uint16_t) 0xB400) +#define LOG_DSP_BASE_C ((uint16_t) 0xC000) + +#define LOG_TOOLS_BASE_C ((uint16_t) 0xF000) + +/* LOG_BASE_C is what was used before expanding the use of the equipment ID. + * TODO: Once all targets are using the "core" diag system, this should be + * ommitted. */ +#define LOG_BASE_C LOG_1X_BASE_C + +/* ------------------------------------------------------------------------- + * Log Codes + * These codes identify the kind of information contained in a log entry. + * They are used in conjunction with the 'code' field of the log entry + * header. The data types associated with each code are defined below. + * ------------------------------------------------------------------------- */ + +/* The upper 4 bits of the 16 bit log entry code specify which type + * of equipment created the log entry. */ + +/* 0 Mobile Station temporal analyzer entry */ +#define LOG_TA_C (0x0 + LOG_1X_BASE_C) + +/* 1 AGC values and closed loop power control entry */ +#define LOG_AGC_PCTL_C (0x1 + LOG_1X_BASE_C) + +/* 2 Forward link frame rates and types entry */ +#define LOG_F_MUX1_C (0x2 + LOG_1X_BASE_C) + +/* 3 Reverse link frame rates and types entry */ +#define LOG_R_MUX1_C (0x3 + LOG_1X_BASE_C) + +/* 4 Access channel message entry */ +#define LOG_AC_MSG_C (0x4 + LOG_1X_BASE_C) + +/* 5 Reverse link traffic channel message entry */ +#define LOG_R_TC_MSG_C (0x5 + LOG_1X_BASE_C) + +/* 6 Sync channel message entry */ +#define LOG_SC_MSG_C (0x6 + LOG_1X_BASE_C) + +/* 7 Paging channel message entry */ +#define LOG_PC_MSG_C (0x7 + LOG_1X_BASE_C) + +/* 8 Forward link traffic channel message entry */ +#define LOG_F_TC_MSG_C (0x8 + LOG_1X_BASE_C) + +/* 9 Forward link vocoder packet entry */ +#define LOG_VOC_FOR_C (0x9 + LOG_1X_BASE_C) + +/* 10 Reverse link vocoder packet entry */ +#define LOG_VOC_REV_C (0xA + LOG_1X_BASE_C) + +/* 11 Temporal analyzer finger info only */ +#define LOG_FING_C (0xB + LOG_1X_BASE_C) + +/* 12 Searcher pathlog info (Reused old SRCH logtype) */ +#define LOG_SRCH_C (0xC + LOG_1X_BASE_C) + +/* 13 Position and speed information read from ETAK */ +#define LOG_ETAK_C (0xD + LOG_1X_BASE_C) + +/* 14 Markov frame statistics */ +#define LOG_MAR_C (0xE + LOG_1X_BASE_C) + +/* 15 New and improved temporal analyzer searcher info */ +#define LOG_SRCH2_C (0xF + LOG_1X_BASE_C) + +/* 16 The Fujitsu handset information */ +#define LOG_HANDSET_C (0x10 + LOG_1X_BASE_C) + +/* 17 Vocoder bit error rate mask */ +#define LOG_ERRMASK_C (0x11 + LOG_1X_BASE_C) + +/* 18 Analog voice channel information */ +#define LOG_ANALOG_INFO_C (0x12 + LOG_1X_BASE_C) + +/* 19 Access probe information */ +#define LOG_ACC_INFO_C (0x13 + LOG_1X_BASE_C) + +/* 20 Position & speed info read from GPS receiver */ +#define LOG_GPS_C (0x14 + LOG_1X_BASE_C) + +/* 21 Test Command information */ +#define LOG_TEST_CMD_C (0x15 + LOG_1X_BASE_C) + +/* 22 Sparse (20ms) AGC / closed loop power control entry */ +#define LOG_S_AGC_PCTL_C (0x16 + LOG_1X_BASE_C) + +/* 23 Notification of a band class change */ +#define LOG_BAND_CHANGE_C (0x17 + LOG_1X_BASE_C) + +/* 24 DM debug messages, if being logged via log services */ +#define LOG_DBG_MSG_C (0x18 + LOG_1X_BASE_C) + +/* 25 General temporal analyzer entry */ +#define LOG_GENRL_TA_C (0x19 + LOG_1X_BASE_C) + +/* 26 General temporal analyzer w/supplemental channels */ +#define LOG_GENRL_TA_SUP_CH_C (0x1A + LOG_1X_BASE_C) + +/* Featurization Removal requested by CMI + #ifdef FEATURE_PLT + */ + +/* 27 Decoder raw bits logging */ +#define LOG_PLT_C (0x1B + LOG_1X_BASE_C) + +/* Featurization Removal requested by CMI + #else + 27 EFS Usage Info - No implementation as yet + #define LOG_EFS_INFO_C (0x1B + LOG_1X_BASE_C) + #endif + */ + +/* 28 Analog Forward Channel */ +#define LOG_ANALOG_FORW_C (0x1C + LOG_1X_BASE_C) + +/* 29 Analog Reverse Channel */ +#define LOG_ANALOG_REVS_C (0x1D + LOG_1X_BASE_C) + +/* 30 Analog Handoff Entry */ +#define LOG_ANALOG_HANDOFF_C (0x1E + LOG_1X_BASE_C) + +/* 31 FM Slot Statistis entry */ +#define LOG_ANALOG_FMSLOT_C (0x1F + LOG_1X_BASE_C) + +/* 32 FOCC Word Sync Count entry */ +#define LOG_ANALOG_WS_COUNT_C (0x20 + LOG_1X_BASE_C) + +/* 33 */ +#define LOG_RLP_PACKET_C (0x21 + LOG_1X_BASE_C) + +/* 34 */ +#define LOG_ASYNC_TCP_SEG_C (0x22 + LOG_1X_BASE_C) + +/* 35 */ +#define LOG_PACKET_DATA_IP_PACKETS_C (0x23 + LOG_1X_BASE_C) + +/* 36 */ +#define LOG_FNBDT_MESSAGE_LOG_C (0x24 + LOG_1X_BASE_C) + +/* Begin IS-2000 LOG features */ + +/* 37 RLP RX Frames logging */ +#define LOG_RLP_RX_FRAMES_C (0x25 + LOG_1X_BASE_C) + +/* 38 RLP TX Frames logging */ +#define LOG_RLP_TX_FRAMES_C (0x26 + LOG_1X_BASE_C) + +/* 39 Reserved for additions to RLP frames */ +#define LOG_RLP_RSVD1_C (0x27 + LOG_1X_BASE_C) + +/* 40 Reserved for additions to RLP frames */ +#define LOG_RLP_RSVD2_C (0x28 + LOG_1X_BASE_C) + +/* 41 Forward Link Frame Types logging */ +#define LOG_FWD_FRAME_TYPES_C (0x29 + LOG_1X_BASE_C) + +/* 42 Reverse Link Frame Types logging */ +#define LOG_REV_FRAME_TYPES_C (0x2A + LOG_1X_BASE_C) + +/* 43 Fast Forward Power Control Parameters logging */ +#define LOG_FFWD_PCTRL_C (0x2B + LOG_1X_BASE_C) + +/* 44 Reverse Power Control Parameters logging */ +#define LOG_REV_PCTRL_C (0x2C + LOG_1X_BASE_C) + +/* 45 Searcher and Finger Information logging */ +#define LOG_SRCH_FING_INFO_C (0x2D + LOG_1X_BASE_C) + +/* 46 Service Configuration logging */ +#define LOG_SVC_CONFIG_C (0x2E + LOG_1X_BASE_C) + +/* 47 Active Set Configuration logging */ +#define LOG_ASET_CONFIG_C (0x2F + LOG_1X_BASE_C) + +/* 48 Quick Paging Channel logging */ +#define LOG_QPCH_C (0x30 + LOG_1X_BASE_C) + +/* 49 RLP Statistics logging */ +#define LOG_RLP_STAT_C (0x31 + LOG_1X_BASE_C) + +/* 50 Simple Test Data Service Option logging */ +#define LOG_STDSO_C (0x32 + LOG_1X_BASE_C) + +/* 51 Pilot Phase Measurement results logging */ +#define LOG_SRCH_PPM_RES_C (0x33 + LOG_1X_BASE_C) + +/* 52 Pilot Phase Measurement Data Base logging */ +#define LOG_SRCH_PPM_DB_C (0x34 + LOG_1X_BASE_C) + +/* 53 Pilot Phase Measurement search results logging */ +#define LOG_SRCH_PPM_C (0x35 + LOG_1X_BASE_C) + +/* 54 IS-801 forward link message */ +#define LOG_GPS_FWD_MSG_C (0x36 + LOG_1X_BASE_C) + +/* 55 IS-801 reverse link message */ +#define LOG_GPS_REV_MSG_C (0x37 + LOG_1X_BASE_C) + +/* 56 GPS search session statistics */ +#define LOG_GPS_STATS_MSG_C (0x38 + LOG_1X_BASE_C) + +/* 57 GPS search results */ +#define LOG_GPS_SRCH_PEAKS_MSG_C (0x39 + LOG_1X_BASE_C) + +/* 58 Factory Testmode logging */ +#define LOG_FTM_C (0x3A + LOG_1X_BASE_C) + +/* 59 Multiple Peak Logging */ +#define LOG_SRCH_GPS_MULTI_PEAKS_INFO_C (0x3B + LOG_1X_BASE_C) + +/* 60 Post processed search results logs */ +#define LOG_SRCH_GPS_POST_PROC_C (0x3C + LOG_1X_BASE_C) + +/* 61 FULL Test Data Service Option logging */ +#define LOG_FTDSO_C (0x3D + LOG_1X_BASE_C) + +/* 62 Bluetooth logging */ +#define LOG_BT_RESERVED_CODES_BASE_C (0x3E + LOG_1X_BASE_C) +/* Keep confusing name for backwards compatibility. */ +#define LOG_BT_BASE_C LOG_BT_RESERVED_CODES_BASE_C + +/* 92 Bluetooth's last log code */ +#define LOG_BT_LAST_C (30 + LOG_BT_RESERVED_CODES_BASE_C) + +/* 93 HDR log codes */ +#define LOG_HDR_RESERVED_CODES_BASE_C (0x5D + LOG_1X_BASE_C) +/* Keep confusing name for backwards compatibility. */ +#define LOG_HDR_BASE_C LOG_HDR_RESERVED_CODES_BASE_C + +/* 143 is HDR's last log code */ +#define LOG_HDR_LAST_C (50 + LOG_HDR_RESERVED_CODES_BASE_C) + +/* 144 IS2000 DCCH Forward link channel */ +#define LOG_FOR_DCCH_MSG_C (0x90 + LOG_1X_BASE_C) +#define LOG_DCCH_FWD_C LOG_FOR_DCCH_MSG_C + +/* 145 IS2000 DCCH Forward link channel */ +#define LOG_REV_DCCH_MSG_C (0x91 + LOG_1X_BASE_C) +#define LOG_DCCH_REV_C LOG_REV_DCCH_MSG_C + +/* 146 IS2000 DCCH Forward link channel */ +#define LOG_ZREX_C (0x92 + LOG_1X_BASE_C) + +/* 147 Active set info logging, similar to ASET_CONFIG, but simpler. */ +#define LOG_ASET_INFO_C (0x93 + LOG_1X_BASE_C) + +/* 148 Pilot Phase Measurement four-shoulder-search resutlts logging */ +#define LOG_SRCH_PPM_4SHOULDER_RES_C (0x94 + LOG_1X_BASE_C) + +/* 149 Extended Pilot Phase Measurement Data Base logging */ +#define LOG_SRCH_EXT_PPM_DB_C (0x95 + LOG_1X_BASE_C) + +/* 150 GPS Visit Parameters */ +#define LOG_GPS_VISIT_PARAMETERS_C (0x96 + LOG_1X_BASE_C) + +/* 151 GPS Measurement */ +#define LOG_GPS_MEASUREMENT_C (0x97 + LOG_1X_BASE_C) + +/* 152 UIM Data */ +#define LOG_UIM_DATA_C (0x98 + LOG_1X_BASE_C) + +/* 153 STDSO plus P2 */ +#define LOG_STDSO_P2_C (0x99 + LOG_1X_BASE_C) + +/* 154 FTDSO plus P2 */ +#define LOG_FTDSO_P2_C (0x9A + LOG_1X_BASE_C) + +/* 155 Search PPM Statistics */ +#define LOG_SRCH_PPM_STATS_C (0x9B + LOG_1X_BASE_C) + +/* 156 PPP Tx Frames */ +#define LOG_PPP_TX_FRAMES_C (0x9C + LOG_1X_BASE_C) + +/* 157 PPP Rx Frames */ +#define LOG_PPP_RX_FRAMES_C (0x9D + LOG_1X_BASE_C) + +/* 158-187 SSL reserved log codes */ +#define LOG_SSL_RESERVED_CODES_BASE_C (0x9E + LOG_1X_BASE_C) +#define LOG_SSL_LAST_C (29 + LOG_SSL_RESERVED_CODES_BASE_C) + +/* 188-199 Puma reserved log codes */ +/* 188 QPCH, version 2 */ +#define LOG_QPCH_VER_2_C (0xBC + LOG_1X_BASE_C) + +/* 189 Enhanced Access Probe */ +#define LOG_EA_PROBE_C (0xBD + LOG_1X_BASE_C) + +/* 190 BCCH Frame Information */ +#define LOG_BCCH_FRAME_INFO_C (0xBE + LOG_1X_BASE_C) + +/* 191 FCCCH Frame Information */ +#define LOG_FCCCH_FRAME_INFO_C (0xBF + LOG_1X_BASE_C) + +/* 192 FDCH Frame Information */ +#define LOG_FDCH_FRAME_INFO_C (0xC0 + LOG_1X_BASE_C) + +/* 193 RDCH Frame Information */ +#define LOG_RDCH_FRAME_INFO_C (0xC1 + LOG_1X_BASE_C) + +/* 194 FFPC Information */ +#define LOG_FFPC_INFO_C (0xC2 + LOG_1X_BASE_C) + +/* 195 RPC Information */ +#define LOG_RPC_INFO_C (0xC3 + LOG_1X_BASE_C) + +/* 196 Searcher and Finger Information */ +#define LOG_SRCH_FING_INFO_VER_2_C (0xC4 + LOG_1X_BASE_C) + +/* 197 Service Configuration, version 2 */ +#define LOG_SRV_CONFIG_VER_2_C (0xC5 + LOG_1X_BASE_C) + +/* 198 Active Set Information, version 2 */ +#define LOG_ASET_INFO_VER_2_C (0xC6 + LOG_1X_BASE_C) + +/* 199 Reduced Active Set */ +#define LOG_REDUCED_ASET_INFO_C (0xC7 + LOG_1X_BASE_C) + +/* 200 Search Triage Info */ +#define LOG_SRCH_TRIAGE_INFO_C (0xC8 + LOG_1X_BASE_C) + +/* 201 RDA Frame Information */ +#define LOG_RDA_FRAME_INFO_C (0xC9 + LOG_1X_BASE_C) + +/* 202 gpsOne fatpath information */ +#define LOG_GPS_FATPATH_INFO_C (0xCA + LOG_1X_BASE_C) + +/* 203 Extended AGC */ +#define LOG_EXTENDED_AGC_C (0xCB + LOG_1X_BASE_C) + +/* 204 Transmit AGC */ +#define LOG_TRANSMIT_AGC_C (0xCC + LOG_1X_BASE_C) + +/* 205 I/Q Offset registers */ +#define LOG_IQ_OFFSET_REGISTERS_C (0xCD + LOG_1X_BASE_C) + +/* 206 DACC I/Q Accumulator registers */ +#define LOG_DACC_IQ_ACCUMULATOR_C (0xCE + LOG_1X_BASE_C) + +/* 207 Register polling results */ +#define LOG_REGISTER_POLLING_RESULTS_C (0xCF + LOG_1X_BASE_C) + +/* 208 System arbitration module */ +#define LOG_AT_SAM_C (0xD0 + LOG_1X_BASE_C) + +/* 209 Diablo searcher finger log */ +#define LOG_DIABLO_SRCH_FING_INFO_C (0xD1 + LOG_1X_BASE_C) + +/* 210 log reserved for dandrus */ +#define LOG_SD20_LAST_ACTION_C (0xD2 + LOG_1X_BASE_C) + +/* 211 log reserved for dandrus */ +#define LOG_SD20_LAST_ACTION_HYBRID_C (0xD3 + LOG_1X_BASE_C) + +/* 212 log reserved for dandrus */ +#define LOG_SD20_SS_OBJECT_C (0xD4 + LOG_1X_BASE_C) + +/* 213 log reserved for dandrus */ +#define LOG_SD20_SS_OBJECT_HYBRID_C (0xD5 + LOG_1X_BASE_C) + +/* 214 log reserved for jpinos */ +#define LOG_BCCH_SIGNALING_C (0xD6 + LOG_1X_BASE_C) + +/* 215 log reserved for jpinos */ +#define LOG_REACH_SIGNALING_C (0xD7 + LOG_1X_BASE_C) + +/* 216 log reserved for jpinos */ +#define LOG_FCCCH_SIGNALING_C (0xD8 + LOG_1X_BASE_C) + +/* 217 RDA Frame Information 2 */ +#define LOG_RDA_FRAME_INFO_2_C (0xD9 + LOG_1X_BASE_C) + +/* 218 */ +#define LOG_GPS_BIT_EDGE_RESULTS_C (0xDA + LOG_1X_BASE_C) + +/* 219 */ +#define LOG_PE_DATA_C (0xDB + LOG_1X_BASE_C) + +/* 220 */ +#define LOG_PE_PARTIAL_DATA_C (0xDC + LOG_1X_BASE_C) + +/* 221 */ +#define LOG_GPS_SINGLE_PEAK_SRCH_RESULTS_C (0xDD + LOG_1X_BASE_C) + +/* 222 */ +#define LOG_SRCH4_SAMPRAM_C (0xDE + LOG_1X_BASE_C) + +/* 223 */ +#define HDR_AN_PPP_TX_FRAMES (0xDF + LOG_1X_BASE_C) + +/* 224 */ +#define HDR_AN_PPP_RX_FRAMES (0xE0 + LOG_1X_BASE_C) + +/* 225 */ +#define LOG_GPS_SCHEDULER_TRACE_C (0xE1 + LOG_1X_BASE_C) + +/* 226 */ +#define LOG_MPEG4_YUV_FRAME_C (0xE2 + LOG_1X_BASE_C) + +/* 227 */ +#define LOG_MPEG4_CLIP_STATS_C (0xE3 + LOG_1X_BASE_C) + +/* 228 */ +#define LOG_MPEG4_CLIP_STATS_VER2_C (0xE4 + LOG_1X_BASE_C) + +/* 226-241 MMEG reserved. */ +#define LOG_MPEG_RESERVED_CODES_BASE_C (0xF1 + LOG_1X_BASE_C) + +/* 242-274 BREW reserved log range */ +#define LOG_BREW_RESERVED_CODES_BASE_C (0xF2 + LOG_1X_BASE_C) +#define LOG_BREW_LAST_C (32 + LOG_BREW_RESERVED_CODES_BASE_C) + +/* 275-339 PPP Extended Frames */ +#define LOG_PPP_FRAMES_RESERVED_CODES_BASE_C (0x113 + LOG_1X_BASE_C) +#define LOG_PPP_FRAMES_LAST_C (64 + LOG_PPP_FRAMES_RESERVED_CODES_BASE_C) + +#define LOG_PPP_EXT_FRAMED_RX_UM_C (0x113 + LOG_1X_BASE_C) +#define LOG_PPP_EXT_FRAMED_RX_RM_C (0x114 + LOG_1X_BASE_C) +#define LOG_PPP_EXT_FRAMED_RX_AN_C (0x115 + LOG_1X_BASE_C) + +#define LOG_PPP_EXT_FRAMED_TX_UM_C (0x123 + LOG_1X_BASE_C) +#define LOG_PPP_EXT_FRAMED_TX_RM_C (0x124 + LOG_1X_BASE_C) +#define LOG_PPP_EXT_FRAMED_TX_AN_C (0x125 + LOG_1X_BASE_C) + +#define LOG_PPP_EXT_UNFRAMED_RX_UM_C (0x133 + LOG_1X_BASE_C) +#define LOG_PPP_EXT_UNFRAMED_RX_RM_C (0x134 + LOG_1X_BASE_C) +#define LOG_PPP_EXT_UNFRAMED_RX_AN_C (0x135 + LOG_1X_BASE_C) + +#define LOG_PPP_EXT_UNFRAMED_TX_UM_C (0x143 + LOG_1X_BASE_C) +#define LOG_PPP_EXT_UNFRAMED_TX_RM_C (0x144 + LOG_1X_BASE_C) +#define LOG_PPP_EXT_UNFRAMED_TX_AN_C (0x145 + LOG_1X_BASE_C) + +/* 340 LOG_PE_DATA_EXT_C */ +#define LOG_PE_DATA_EXT_C (0x154 + LOG_1X_BASE_C) + +/* REX Subsystem logs */ +#define LOG_MEMDEBUG_C (0x155 + LOG_1X_BASE_C) +#define LOG_SYSPROFILE_C (0x156 + LOG_1X_BASE_C) +#define LOG_TASKPROFILE_C (0x157 + LOG_1X_BASE_C) +#define LOG_COREDUMP_C (0x158 + LOG_1X_BASE_C) + +/* 341-349 REX subsystem logs */ +#define LOG_REX_RESERVED_CODES_BASE_C (0x155 + LOG_1X_BASE_C) +#define LOG_REX_LAST_C (8 + LOG_REX_RESERVED_CODES_BASE_C) + +/* 350 LOG_PE_PARTIAL_DATA_EXT_C */ +#define LOG_PE_PARTIAL_DATA_EXT_C (0x15E + LOG_1X_BASE_C) + +/* 351 LOG_DIAG_STRESS_TEST_C */ +#define LOG_DIAG_STRESS_TEST_C (0x15F + LOG_1X_BASE_C) + +/* 352 LOG_WMS_READ_C */ +#define LOG_WMS_READ_C (0x160 + LOG_1X_BASE_C) + +/* 353 Search Triage Info Version 2 */ +#define LOG_SRCH_TRIAGE_INFO2_C (0x161 + LOG_1X_BASE_C) + +/* 354 RLP Rx FDCH Frames */ +#define LOG_RLP_RX_FDCH_FRAMES_C (0x162 + LOG_1X_BASE_C) + +/* 355 RLP Tx FDCH Frames */ +#define LOG_RLP_TX_FDCH_FRAMES_C (0x163 + LOG_1X_BASE_C) + +/* 356-371 QTV subsystem logs */ +#define LOG_QTV_RESERVED_CODES_BASE_C (0x164 + LOG_1X_BASE_C) +#define LOG_QTV_LAST_C (15 + LOG_QTV_RESERVED_CODES_BASE_C) + +/* 372 Searcher 4 1X */ +#define LOG_SRCH4_1X_C (0x174 + LOG_1X_BASE_C) + +/* 373 Searcher sleep statistics */ +#define LOG_SRCH_SLEEP_STATS_C (0x175 + LOG_1X_BASE_C) + +/* 374 Service Configuration, version 3 */ +#define LOG_SRV_CONFIG_VER_3_C (0x176 + LOG_1X_BASE_C) + +/* 375 Searcher 4 HDR */ +#define LOG_SRCH4_HDR_C (0x177 + LOG_1X_BASE_C) + +/* 376 Searcher 4 AFLT */ +#define LOG_SRCH4_AFLT_C (0x178 + LOG_1X_BASE_C) + +/* 377 Enhanced Finger Information */ +#define LOG_ENH_FING_INFO_C (0x179 + LOG_1X_BASE_C) + +/* 378 DV Information */ +#define LOG_DV_INFO_C (0x17A + LOG_1X_BASE_C) + +/* 379 WMS set routes information */ +#define LOG_WMS_SET_ROUTES_C (0x17B + LOG_1X_BASE_C) + +/* 380 FTM Version 2 Logs */ +#define LOG_FTM_VER_2_C (0x17C + LOG_1X_BASE_C) + +/* 381 GPS Multipeak logging */ +#define LOG_SRCH_GPS_MULTI_PEAKS_SIMPLIFIED_INFO_C (0x17D + LOG_1X_BASE_C) + +/* 382 GPS Multipeak logging */ +#define LOG_SRCH_GPS_MULTI_PEAKS_VERBOSE_INFO_C (0x17E + LOG_1X_BASE_C) + +/* 383-403 HDR reserved logs */ +#define LOG_HDR_RESERVED_CODES_BASE_2_C (0x17F + LOG_1X_BASE_C) +#define LOG_HDR_LAST_2_C (20 + LOG_HDR_RESERVED_CODES_BASE_2_C) + +/* RLP Rx - PDCH partial MuxPDU5 frames */ +#define LOG_RLP_RX_PDCH_PARTIAL_MUXPDU5_FRAMES_C (0x194 + LOG_1X_BASE_C) + +/* RLP Tx - PDCH partial MuxPDU5 frames */ +#define LOG_RLP_TX_PDCH_PARTIAL_MUXPDU5_FRAMES_C (0x195 + LOG_1X_BASE_C) + +/* RLP Rx internal details */ +#define LOG_RLP_RX_INTERNAL_DETAILS_C (0x196 + LOG_1X_BASE_C) + +/* RLP Tx internal details */ +#define LOG_RLP_TX_INTERNAL_DETAILS_C (0x197 + LOG_1X_BASE_C) + +/* MPEG4 Clip Statistics version 3 */ +#define LOG_MPEG4_CLIP_STATS_VER3_C (0x198 + LOG_1X_BASE_C) + +/* Mobile IP Performance */ +#define LOG_MOBILE_IP_PERFORMANCE_C (0x199 + LOG_1X_BASE_C) + +/* 410-430 Searcher reserved logs */ +#define LOG_SEARCHER_RESERVED_CODES_BASE_C (0x19A + LOG_1X_BASE_C) +#define LOG_SEARCHER_LAST_2_C (21 + LOG_SEARCHER_RESERVED_CODES_BASE_C) + +/* 432-480 QTV reserved logs */ +#define LOG_QTV2_RESERVED_CODES_BASE_C (0x1B0 + LOG_1X_BASE_C) +#define LOG_QTV2_LAST_C (48 + LOG_QTV2_RESERVED_CODES_BASE_C) + +#define LOG_QTV_PDS2_STATS (0x1B6 + LOG_1X_BASE_C) +#define LOG_QTV_PDS2_GET_REQUEST (0x1B7 + LOG_1X_BASE_C) +#define LOG_QTV_PDS2_GET_RESP_HEADER (0x1B8 + LOG_1X_BASE_C) +#define LOG_QTV_PDS2_GET_RESP_PCKT (0x1B9 + LOG_1X_BASE_C) +#define LOG_QTV_CMX_AUDIO_INPUT_DATA_C (0x1BA + LOG_1X_BASE_C) +#define LOG_QTV_RTSP_OPTIONS_C (0x1BB + LOG_1X_BASE_C) +#define LOG_QTV_RTSP_GET_PARAMETER_C (0x1BC + LOG_1X_BASE_C) +#define LOG_QTV_RTSP_SET_PARAMETER_C (0x1BD + LOG_1X_BASE_C) +#define LOG_QTV_VIDEO_BITSTREAM (0x1BE + LOG_1X_BASE_C) +#define LOG_ARM_VIDEO_DECODE_STATS (0x1BF + LOG_1X_BASE_C) +#define LOG_QTV_DSP_SLICE_BUFFER_C (0x1C0 + LOG_1X_BASE_C) +#define LOG_QTV_CMD_LOGGING_C (0x1C1 + LOG_1X_BASE_C) +#define LOG_QTV_AUDIO_FRAME_PTS_INFO_C (0x1C2 + LOG_1X_BASE_C) +#define LOG_QTV_VIDEO_FRAME_DECODE_INFO_C (0x1C3 + LOG_1X_BASE_C) +#define LOG_QTV_RTCP_COMPOUND_RR_C (0x1C4 + LOG_1X_BASE_C) +#define LOG_QTV_FRAME_BUFFER_RELEASE_REASON_C (0x1C5 + LOG_1X_BASE_C) +#define LOG_QTV_AUDIO_CHANNEL_SWITCH_FRAME_C (0x1C6 + LOG_1X_BASE_C) +#define LOG_QTV_RTP_DECRYPTED_PKT_C (0x1C7 + LOG_1X_BASE_C) +#define LOG_QTV_PCR_DRIFT_RATE_C (0x1C8 + LOG_1X_BASE_C) + +/* GPS PDSM logs */ +#define LOG_PDSM_POSITION_REPORT_CALLBACK_C (0x1E1 + LOG_1X_BASE_C) +#define LOG_PDSM_PD_EVENT_CALLBACK_C (0x1E2 + LOG_1X_BASE_C) +#define LOG_PDSM_PA_EVENT_CALLBACK_C (0x1E3 + LOG_1X_BASE_C) +#define LOG_PDSM_NOTIFY_VERIFY_REQUEST_C (0x1E4 + LOG_1X_BASE_C) +#define LOG_PDSM_RESERVED1_C (0x1E5 + LOG_1X_BASE_C) +#define LOG_PDSM_RESERVED2_C (0x1E6 + LOG_1X_BASE_C) + +/* Searcher Demodulation Status log */ +#define LOG_SRCH_DEMOD_STATUS_C (0x1E7 + LOG_1X_BASE_C) + +/* Searcher Call Statistics log */ +#define LOG_SRCH_CALL_STATISTICS_C (0x1E8 + LOG_1X_BASE_C) + +/* GPS MS-MPC Forward link */ +#define LOG_MS_MPC_FWD_LINK_C (0x1E9 + LOG_1X_BASE_C) + +/* GPS MS-MPC Reverse link */ +#define LOG_MS_MPC_REV_LINK_C (0x1EA + LOG_1X_BASE_C) + +/* Protocol Services Data */ +#define LOG_DATA_PROTOCOL_LOGGING_C (0x1EB + LOG_1X_BASE_C) + +/* MediaFLO reserved log codes */ +#define LOG_MFLO_RESERVED_CODES_BASE_C (0x1EC + LOG_1X_BASE_C) +#define LOG_MFLO_LAST_C (99 + LOG_MFLO_RESERVED_CODES_BASE_C) + +/* GPS demodulation tracking header info */ +#define LOG_GPS_DEMOD_TRACKING_HEADER_C (0x250 + LOG_1X_BASE_C) + +/* GPS demodulation tracking results */ +#define LOG_GPS_DEMOD_TRACKING_C (0x251 + LOG_1X_BASE_C) + +/* GPS bit edge logs from demod tracking */ +#define LOG_GPS_DEMOD_BIT_EDGE_C (0x252 + LOG_1X_BASE_C) + +/* GPS demodulation soft decisions */ +#define LOG_GPS_DEMOD_SOFT_DECISIONS_C (0x253 + LOG_1X_BASE_C) + +/* GPS post-processed demod tracking results */ +#define LOG_GPS_DEMOD_TRACKING_POST_PROC_C (0x254 + LOG_1X_BASE_C) + +/* GPS subframe log */ +#define LOG_GPS_DEMOD_SUBFRAME_C (0x255 + LOG_1X_BASE_C) + +/* F-CPCCH Quality Information */ +#define LOG_F_CPCCH_QUALITY_INFO_C (0x256 + LOG_1X_BASE_C) + +/* Reverse PDCCH/PDCH Frame Information */ +#define LOG_R_PDCCH_R_PDCH_FRAME_INFO_C (0x257 + LOG_1X_BASE_C) + +/* Forward G Channel Information */ +#define LOG_F_GCH_INFO_C (0x258 + LOG_1X_BASE_C) + +/* Forward G Channel Frame Information */ +#define LOG_F_GCH_FRAME_INFO_C (0x259 + LOG_1X_BASE_C) + +/* Forward RC Channel Information */ +#define LOG_F_RCCH_INFO_C (0x25A + LOG_1X_BASE_C) + +/* Forward ACK Channel Information */ +#define LOG_F_ACKCH_INFO_C (0x25B + LOG_1X_BASE_C) + +/* Forward ACK Channel ACKDA Information */ +#define LOG_F_ACKCH_ACKDA_C (0x25C + LOG_1X_BASE_C) + +/* Reverse REQ Channel Information */ +#define LOG_R_REQCH_INFO_C (0x25D + LOG_1X_BASE_C) + +/* Sleep Task Statistics */ +#define LOG_SLEEP_STATS_C (0x25E + LOG_1X_BASE_C) + +/* Sleep controller statistics 1X */ +#define LOG_1X_SLEEP_CONTROLLER_STATS_C (0x25F + LOG_1X_BASE_C) + +/* Sleep controller statistics HDR */ +#define LOG_HDR_SLEEP_CONTROLLER_STATS_C (0x260 + LOG_1X_BASE_C) + +/* Sleep controller statistics GSM */ +#define LOG_GSM_SLEEP_CONTROLLER_STATS_C (0x261 + LOG_1X_BASE_C) + +/* Sleep controller statistics WCDMA */ +#define LOG_WCDMA_SLEEP_CONTROLLER_STATS_C (0x262 + LOG_1X_BASE_C) + +/* Sleep task and controller reserved logs */ +#define LOG_SLEEP_APPS_STATS_C (0x263 + LOG_1X_BASE_C) +#define LOG_SLEEP_STATS_RESERVED2_C (0x264 + LOG_1X_BASE_C) +#define LOG_SLEEP_STATS_RESERVED3_C (0x265 + LOG_1X_BASE_C) + +/* DV Information placeholder channel logs */ +#define LOG_PDCCH_LO_SELECTED_C (0x266 + LOG_1X_BASE_C) +#define LOG_PDCCH_HI_SELECTED_C (0x267 + LOG_1X_BASE_C) +#define LOG_WALSH_SELECTED_C (0x268 + LOG_1X_BASE_C) +#define LOG_PDCH_BE_SELECTED_C (0x269 + LOG_1X_BASE_C) +#define LOG_PDCCH_LLR_SELECTED_C (0x26A + LOG_1X_BASE_C) +#define LOG_CQI_ACK_LO_SELECTED_C (0x26B + LOG_1X_BASE_C) +#define LOG_CQI_ACK_HI_SELECTED_C (0x26C + LOG_1X_BASE_C) +#define LOG_RL_GAIN_SELECTED_C (0x26D + LOG_1X_BASE_C) +#define LOG_PDCCH0_SNDA_SELECTED_C (0x26E + LOG_1X_BASE_C) +#define LOG_PDCCH1_SNDA_SELECTED_C (0x26F + LOG_1X_BASE_C) + +/* 624 WMS Message List */ +#define LOG_WMS_MESSAGE_LIST_C (0x270 + LOG_1X_BASE_C) + +/* 625 Multimode Generic SIM Driver Interface */ +#define LOG_MM_GENERIC_SIM_DRIVER_C (0x271 + LOG_1X_BASE_C) + +/* 626 Generic SIM Toolkit Task */ +#define LOG_GENERIC_SIM_TOOLKIT_TASK_C (0x272 + LOG_1X_BASE_C) + +/* 627 Call Manager Phone events log */ +#define LOG_CM_PH_EVENT_C (0x273 + LOG_1X_BASE_C) + +/* 628 WMS Set Message List */ +#define LOG_WMS_SET_MESSAGE_LIST_C (0x274 + LOG_1X_BASE_C) + +/* 629-704 HDR reserved logs */ +#define LOG_HDR_RESERVED_CODES_BASE_3_C (0x275 + LOG_1X_BASE_C) +#define LOG_HDR_LAST_3_C (75 + LOG_HDR_RESERVED_CODES_BASE_3_C) + +/* 705 Call Manager call event log */ +#define LOG_CM_CALL_EVENT_C (0x2C1 + LOG_1X_BASE_C) + +/* 706-738 QVP reserved logs */ +#define LOG_QVP_RESERVED_CODES_BASE_C (0x2C2 + LOG_1X_BASE_C) +#define LOG_QVP_LAST_C (32 + LOG_QVP_RESERVED_CODES_BASE_C) + +/* 739 GPS PE Position Report log */ +#define LOG_GPS_PE_POSITION_REPORT_C (0x2E3 + LOG_1X_BASE_C) + +/* 740 GPS PE Position Report Extended log */ +#define LOG_GPS_PE_POSITION_REPORT_EXT_C (0x2E4 + LOG_1X_BASE_C) + +/* 741 log */ +#define LOG_MDDI_HOST_STATS_C (0x2E5 + LOG_1X_BASE_C) + +/* GPS Decoded Ephemeris */ +#define LOG_GPS_DECODED_EPHEMERIS_C (0x2E6 + LOG_1X_BASE_C) + +/* GPS Decoded Almanac */ +#define LOG_GPS_DECODED_ALMANAC_C (0x2E7 + LOG_1X_BASE_C) + +/* Transceiver Resource Manager */ +#define LOG_TRANSCEIVER_RESOURCE_MGR_C (0x2E8 + LOG_1X_BASE_C) + +/* GPS Position Engine Info */ +#define LOG_GPS_POSITION_ENGINE_INFO_C (0x2E9 + LOG_1X_BASE_C) + +/* 746-810 RAPTOR reserved log range */ +#define LOG_RAPTOR_RESERVED_CODES_BASE_C (0x2EA + LOG_1X_BASE_C) +#define LOG_RAPTOR_LAST_C (64 + LOG_RAPTOR_RESERVED_CODES_BASE_C) + +/* QOS Specification Logging */ + +/* QOS Requested Log */ +#define LOG_QOS_REQUESTED_C (0x32B + LOG_1X_BASE_C) + +/* QOS Granted Log */ +#define LOG_QOS_GRANTED_C (0x32C + LOG_1X_BASE_C) + +/* QOS State Log */ +#define LOG_QOS_STATE_C (0x32D + LOG_1X_BASE_C) + +#define LOG_QOS_MODIFIED_C (0x32E + LOG_1X_BASE_C) + +#define LOG_QDJ_ENQUEUE_C (0x32F + LOG_1X_BASE_C) +#define LOG_QDJ_DEQUEUE_C (0x330 + LOG_1X_BASE_C) +#define LOG_QDJ_UPDATE_C (0x331 + LOG_1X_BASE_C) +#define LOG_QDTX_ENCODER_C (0x332 + LOG_1X_BASE_C) +#define LOG_QDTX_DECODER_C (0x333 + LOG_1X_BASE_C) + +#define LOG_PORT_ASSIGNMENT_STATUS_C (0x334 + LOG_1X_BASE_C) + +/* Protocol Services reserved log codes */ +#define LOG_PS_RESERVED_CODES_BASE_C (0x335 + LOG_1X_BASE_C) +#define LOG_PS_LAST_C (25 + LOG_PS_RESERVED_C) + +#define LOG_PS_STAT_IP_C (0x335 + LOG_1X_BASE_C) +#define LOG_PS_STAT_GLOBAL_IPV4_C (0x335 + LOG_1X_BASE_C) +#define LOG_PS_STAT_GLOBAL_IPV6_C (0x336 + LOG_1X_BASE_C) +#define LOG_PS_STAT_GLOBAL_ICMPV4_C (0x337 + LOG_1X_BASE_C) +#define LOG_PS_STAT_GLOBAL_ICMPV6_C (0x338 + LOG_1X_BASE_C) +#define LOG_PS_STAT_GLOBAL_TCP_C (0x339 + LOG_1X_BASE_C) +#define LOG_PS_STAT_GLOBAL_UDP_C (0x33A + LOG_1X_BASE_C) + +/* Protocol Services describe all TCP instances */ +#define LOG_PS_STAT_DESC_ALL_TCP_INST_C (0x33B + LOG_1X_BASE_C) + +/* Protocol Services describe all memory pool instances */ +#define LOG_PS_STAT_DESC_ALL_MEM_POOL_INST_C (0x33C + LOG_1X_BASE_C) + +/* Protocol Services describe all IFACE instances */ +#define LOG_PS_STAT_DESC_ALL_IFACE_INST_C (0x33D + LOG_1X_BASE_C) + +/* Protocol Services describe all PPP instances */ +#define LOG_PS_STAT_DESC_ALL_PPP_INST_C (0x33E + LOG_1X_BASE_C) + +/* Protocol Services describe all ARP instances */ +#define LOG_PS_STAT_DESC_ALL_ARP_INST_C (0x33F + LOG_1X_BASE_C) + +/* Protocol Services describe delta instance */ +#define LOG_PS_STAT_DESC_DELTA_INST_C (0x340 + LOG_1X_BASE_C) + +/* Protocol Services instance TCP statistics */ +#define LOG_PS_STAT_TCP_INST_C (0x341 + LOG_1X_BASE_C) + +/* Protocol Services instance UDP statistics */ +#define LOG_PS_STAT_UDP_INST_C (0x342 + LOG_1X_BASE_C) + +/* Protocol Services instance PPP statistics */ +#define LOG_PS_STAT_PPP_INST_C (0x343 + LOG_1X_BASE_C) + +/* Protocol Services instance IFACE statistics */ +#define LOG_PS_STAT_IFACE_INST_C (0x344 + LOG_1X_BASE_C) + +/* Protocol Services instance memory statistics */ +#define LOG_PS_STAT_MEM_INST_C (0x345 + LOG_1X_BASE_C) + +/* Protocol Services instance flow statistics */ +#define LOG_PS_STAT_FLOW_INST_C (0x346 + LOG_1X_BASE_C) + +/* Protocol Services instance physical link statistics */ +#define LOG_PS_STAT_PHYS_LINK_INST_C (0x347 + LOG_1X_BASE_C) + +/* Protocol Services instance ARP statistics */ +#define LOG_PS_STAT_ARP_INST_C (0x348 + LOG_1X_BASE_C) + +/* Protocol Services instance LLC statistics */ +#define LOG_PS_STAT_LLC_INST_C (0x349 + LOG_1X_BASE_C) + +/* Protocol Services instance IPHC statistics */ +#define LOG_PS_STAT_IPHC_INST_C (0x34A + LOG_1X_BASE_C) + +/* Protocol Services instance ROHC statistics */ +#define LOG_PS_STAT_ROHC_INST_C (0x34B + LOG_1X_BASE_C) + +/* Protocol Services instance RSVP statistics */ +#define LOG_PS_STAT_RSVP_INST_C (0x34C + LOG_1X_BASE_C) + +/* Protocol Services describe all LLC instances */ +#define LOG_PS_STAT_DESC_ALL_LLC_INST_C (0x34D + LOG_1X_BASE_C) + +/* Protocol Services describe all RSVP instances */ +#define LOG_PS_STAT_DESC_ALL_RSVP_INST_C (0x34E + LOG_1X_BASE_C) + +/* Call Manager Serving System event log */ +#define LOG_CM_SS_EVENT_C (0x34F + LOG_1X_BASE_C) + +/* VcTcxo manager’s automatic frequency control log */ +#define LOG_TCXOMGR_AFC_DATA_C (0x350 + LOG_1X_BASE_C) + +/* Clock transactions and general clocks status log */ +#define LOG_CLOCK_C (0x351 + LOG_1X_BASE_C) + +/* GPS search processed peak results and their associated search parameters */ +#define LOG_GPS_PROCESSED_PEAK_C (0x352 + LOG_1X_BASE_C) + +#define LOG_MDSP_LOG_CHUNKS_C (0x353 + LOG_1X_BASE_C) + +/* Periodic RSSI update log */ +#define LOG_WLAN_RSSI_UPDATE_C (0x354 + LOG_1X_BASE_C) + +/* Periodic Link Layer statistics log */ +#define LOG_WLAN_LL_STAT_C (0x355 + LOG_1X_BASE_C) + +/* QOS Extended State Log */ +#define LOG_QOS_STATE_EX_C (0x356 + LOG_1X_BASE_C) + +/* Bluetooth host HCI transmitted data */ +#define LOG_BT_HOST_HCI_TX_C (0x357 + LOG_1X_BASE_C) + +/* Bluetooth host HCI received data */ +#define LOG_BT_HOST_HCI_RX_C (0x358 + LOG_1X_BASE_C) + +/* Internal - GPS PE Position Report Part 3 */ +#define LOG_GPS_PE_POSITION_REPORT_PART3_C (0x359 + LOG_1X_BASE_C) + +/* Extended log code which logs requested QoS */ +#define LOG_QOS_REQUESTED_EX_C (0x35A + LOG_1X_BASE_C) + +/* Extended log code which logs granted QoS */ +#define LOG_QOS_GRANTED_EX_C (0x35B + LOG_1X_BASE_C) + +/* Extended log code which logs modified QoS */ +#define LOG_QOS_MODIFIED_EX_C (0x35C + LOG_1X_BASE_C) + +/* Bus Monitor Profiling Info */ +#define LOG_BUS_MON_PROF_INFO_C (0x35D + LOG_1X_BASE_C) + +/* Pilot Phase Measurement Search results */ +#define LOG_SRCH_PPM_RES_VER_2_C (0x35E + LOG_1X_BASE_C) + +/* Pilot Phase Measurement Data Base */ +#define LOG_SRCH_PPM_DB_VER_2_C (0x35F + LOG_1X_BASE_C) + +/* Pilot Phase Measurement state machine */ +#define LOG_PPM_SM_C (0x360 + LOG_1X_BASE_C) + +/* Robust Header Compression - Compressor */ +#define LOG_ROHC_COMPRESSOR_C (0x361 + LOG_1X_BASE_C) + +/* Robust Header Compression - Decompressor */ +#define LOG_ROHC_DECOMPRESSOR_C (0x362 + LOG_1X_BASE_C) + +/* Robust Header Compression - Feedback Compressor */ +#define LOG_ROHC_FEEDBACK_COMPRESSOR_C (0x363 + LOG_1X_BASE_C) + +/* Robust Header Compression - Feedback Decompressor */ +#define LOG_ROHC_FEEDBACK_DECOMPRESSOR_C (0x364 + LOG_1X_BASE_C) + +/* Bluetooth HCI commands */ +#define LOG_BT_HCI_CMD_C (0x365 + LOG_1X_BASE_C) + +/* Bluetooth HCI events */ +#define LOG_BT_HCI_EV_C (0x366 + LOG_1X_BASE_C) + +/* Bluetooth HCI Transmitted ACL data */ +#define LOG_BT_HCI_TX_ACL_C (0x367 + LOG_1X_BASE_C) + +/* Bluetooth HCI Received ACL data */ +#define LOG_BT_HCI_RX_ACL_C (0x368 + LOG_1X_BASE_C) + +/* Bluetooth SOC H4 Deep Sleep */ +#define LOG_BT_SOC_H4DS_C (0x369 + LOG_1X_BASE_C) + +/* UMTS to CDMA Handover Message */ +#define LOG_UMTS_TO_CDMA_HANDOVER_MSG_C (0x36A + LOG_1X_BASE_C) + +/* Graphic Event Data */ +#define LOG_PROFILER_GRAPHIC_DATA_C (0x36B + LOG_1X_BASE_C) + +/* Audio Event Data */ +#define LOG_PROFILER_AUDIO_DATA_C (0x36C + LOG_1X_BASE_C) + +/* GPS Spectral Information */ +#define LOG_GPS_SPECTRAL_INFO_C (0x36D + LOG_1X_BASE_C) + +/* AHB Performance Monitor LOG data */ +#define LOG_APM_C (0x36E + LOG_1X_BASE_C) + +/* GPS Clock Report */ +#define LOG_CONVERGED_GPS_CLOCK_REPORT_C (0x36F + LOG_1X_BASE_C) + +/* GPS Position Report */ +#define LOG_CONVERGED_GPS_POSITION_REPORT_C (0x370 + LOG_1X_BASE_C) + +/* GPS Measurement Report */ +#define LOG_CONVERGED_GPS_MEASUREMENT_REPORT_C (0x371 + LOG_1X_BASE_C) + +/* GPS RF Status Report */ +#define LOG_CONVERGED_GPS_RF_STATUS_REPORT_C (0x372 + LOG_1X_BASE_C) + +/* VOIP To CDMA Handover Message - Obsoleted by 0x138B - 0x138D */ +#define LOG_VOIP_TO_CDMA_HANDOVER_MSG_C (0x373 + LOG_1X_BASE_C) + +/* GPS Prescribed Dwell Result */ +#define LOG_GPS_PRESCRIBED_DWELL_RESULT_C (0x374 + LOG_1X_BASE_C) + +/* CGPS IPC Data */ +#define LOG_CGPS_IPC_DATA_C (0x375 + LOG_1X_BASE_C) + +/* CGPS Non IPC Data */ +#define LOG_CGPS_NON_IPC_DATA_C (0x376 + LOG_1X_BASE_C) + +/* CGPS Session Report */ +#define LOG_CGPS_REP_EVT_LOG_PACKET_C (0x377 + LOG_1X_BASE_C) + +/* CGPS PDSM Get Position */ +#define LOG_CGPS_PDSM_GET_POSITION_C (0x378 + LOG_1X_BASE_C) + +/* CGPS PDSM Set Parameters */ +#define LOG_CGPS_PDSM_SET_PARAMETERS_C (0x379 + LOG_1X_BASE_C) + +/* CGPS PDSM End Session */ +#define LOG_CGPS_PDSM_END_SESSION_C (0x37A + LOG_1X_BASE_C) + +/* CGPS PDSM notify Verify Response */ +#define LOG_CGPS_PDSM_NOTIFY_VERIFY_RESP_C (0x37B + LOG_1X_BASE_C) + +/* CGPS PDSM Position Report Callback */ +#define LOG_CGPS_PDSM_POSITION_REPORT_CALLBACK_C (0x37C + LOG_1X_BASE_C) + +/* CGPS PDSM PD Event Callback */ +#define LOG_CGPS_PDSM_PD_EVENT_CALLBACK_C (0x37D + LOG_1X_BASE_C) + +/* CGPS PDSM PA Event Callback */ +#define LOG_CGPS_PDSM_PA_EVENT_CALLBACK_C (0x37E + LOG_1X_BASE_C) + +/* CGPS PDSM notify Verify Request Callback */ +#define LOG_CGPS_PDSM_NOTIFY_VERIFY_REQUEST_C (0x37F + LOG_1X_BASE_C) + +/* CGPS PDSM PD Command Error Callback */ +#define LOG_CGPS_PDSM_PD_CMD_ERR_CALLBACK_C (0x380 + LOG_1X_BASE_C) + +/* CGPS PDSM PA Command Error Callback */ +#define LOG_CGPS_PDSM_PA_CMD_ERR_CALLBACK_C (0x381 + LOG_1X_BASE_C) + +/* CGPS PDSM Position Error */ +#define LOG_CGPS_PDSM_POS_ERROR_C (0x382 + LOG_1X_BASE_C) + +/* CGPS PDSM Extended Status Position Report */ +#define LOG_CGPS_PDSM_EXT_STATUS_POS_REPORT_C (0x383 + LOG_1X_BASE_C) + +/* CGPS PDSM Extended Status NMEA Report */ +#define LOG_CGPS_PDSM_EXT_STATUS_NMEA_REPORT_C (0x384 + LOG_1X_BASE_C) + +/* CGPS PDSM Extended Status Measurement Report */ +#define LOG_CGPS_PDSM_EXT_STATUS_MEAS_REPORT_C (0x385 + LOG_1X_BASE_C) + +/* CGPS Report Server TX Packet */ +#define LOG_CGPS_REP_SVR_TX_LOG_PACKET_C (0x386 + LOG_1X_BASE_C) + +/* CGPS Report Server RX Packet */ +#define LOG_CGPS_REP_SVR_RX_LOG_PACKET_C (0x387 + LOG_1X_BASE_C) + +/* UMTS To CDMA Handover Paging Channel Message */ +#define LOG_UMTS_TO_CDMA_HANDOVER_PCH_MSG_C (0x388 + LOG_1X_BASE_C) + +/* UMTS To CDMA Handover Traffic Channel Message */ +#define LOG_UMTS_TO_CDMA_HANDOVER_TCH_MSG_C (0x389 + LOG_1X_BASE_C) + +/* Converged GPS IQ Report */ +#define LOG_CONVERGED_GPS_IQ_REPORT_C (0x38A + LOG_1X_BASE_C) + +/* VOIP To CDMA Paging Channel Handover Message */ +#define LOG_VOIP_TO_CDMA_PCH_HANDOVER_MSG_C (0x38B + LOG_1X_BASE_C) + +/* VOIP To CDMA Access Channel Handover Message */ +#define LOG_VOIP_TO_CDMA_ACH_HANDOVER_MSG_C (0x38C + LOG_1X_BASE_C) + +/* VOIP To CDMA Forward Traffic Channel Handover Message */ +#define LOG_VOIP_TO_CDMA_FTC_HANDOVER_MSG_C (0x38D + LOG_1X_BASE_C) + +/* QMI reserved logs */ +#define LOG_QMI_RESERVED_CODES_BASE_C (0x38E + LOG_1X_BASE_C) +#define LOG_QMI_LAST_C (32 + LOG_QMI_RESERVED_CODES_BASE_C) + +/* QOS Info Code Update Log */ +#define LOG_QOS_INFO_CODE_UPDATE_C (0x3AF + LOG_1X_BASE_C) + +/* Transmit(Uplink) Vocoder PCM Packet Log */ +#define LOG_TX_PCM_PACKET_C (0x3B0 + LOG_1X_BASE_C) + +/* Audio Vocoder Data Paths */ +#define LOG_AUDVOC_DATA_PATHS_PACKET_C (0x3B0 + LOG_1X_BASE_C) + +/* Receive(Downlink) Vocoder PCM Packet Log */ +#define LOG_RX_PCM_PACKET_C (0x3B1 + LOG_1X_BASE_C) + +/* CRC of YUV frame log */ +#define LOG_DEC_CRC_FRAME_C (0x3B2 + LOG_1X_BASE_C) + +/* FLUTE Session Information */ +#define LOG_FLUTE_SESSION_INFO_C (0x3B3 + LOG_1X_BASE_C) + +/* FLUTE ADP File Information */ +#define LOG_FLUTE_ADP_FILE_INFO_C (0x3B4 + LOG_1X_BASE_C) + +/* FLUTE File Request Information */ +#define LOG_FLUTE_FILE_REQ_INFO_C (0x3B5 + LOG_1X_BASE_C) + +/* FLUTE FDT Instance Information */ +#define LOG_FLUTE_FDT_INST_C (0x3B6 + LOG_1X_BASE_C) + +/* FLUTE FDT Information */ +#define LOG_FLUTE_FDT_INFO_C (0x3B7 + LOG_1X_BASE_C) + +/* FLUTE File Log Packet Information */ +#define LOG_FLUTE_FILE_INFO_C (0x3B8 + LOG_1X_BASE_C) + +/* 3G 1X Parameter Overhead Information */ +#define LOG_VOIP_TO_CDMA_3G1X_PARAMETERS_C (0x3B9 + LOG_1X_BASE_C) + +/* CGPS ME Job Info */ +#define LOG_CGPS_ME_JOB_INFO_C (0x3BA + LOG_1X_BASE_C) + +/* CGPS ME SV Lists */ +#define LOG_CPGS_ME_SV_LISTS_C (0x3BB + LOG_1X_BASE_C) + +/* Flexible Profiling Status */ +#define LOG_PROFDIAG_GEN_STATUS_C (0x3BC + LOG_1X_BASE_C) + +/* Flexible Profiling Results */ +#define LOG_PROFDIAG_GEN_PROF_C (0x3BD + LOG_1X_BASE_C) + +/* FLUTE ADP File Content Log Packet Information */ +#define LOG_FLUTE_ADP_FILE_C (0x3BE + LOG_1X_BASE_C) + +/* FLUTE FDT Instance File Content Log Packet Information */ +#define LOG_FLUTE_FDT_INST_FILE_C (0x3BF + LOG_1X_BASE_C) + +/* FLUTE FDT Entries Information */ +#define LOG_FLUTE_FDT_ENTRIES_INFO_C (0x3C0 + LOG_1X_BASE_C) + +/* FLUTE File Contents Log Packet Information */ +#define LOG_FLUTE_FILE_C (0x3C1 + LOG_1X_BASE_C) + +/* CGPS ME Time-Transfer Info */ +#define LOG_CGPS_ME_TIME_TRANSFER_INFO_C (0x3C2 + LOG_1X_BASE_C) + +/* CGPS ME UMTS Time-Tagging Info */ +#define LOG_CGPS_ME_UMTS_TIME_TAGGING_INFO_C (0x3C3 + LOG_1X_BASE_C) + +/* CGPS ME Generic Time Estimate Put lnfo */ +#define LOG_CGPS_ME_TIME_EST_PUT_INFO_C (0x3C4 + LOG_1X_BASE_C) + +/* CGPS ME Generic Freq Estimate Put lnfo */ +#define LOG_CGPS_ME_FREQ_EST_PUT_INFO_C (0x3C5 + LOG_1X_BASE_C) + +/* CGPS Slow Clock Report */ +#define LOG_CGPS_SLOW_CLOCK_REPORT_C (0x3C6 + LOG_1X_BASE_C) + +/* Converged GPS Medium Grid */ +#define LOG_CONVERGED_GPS_MEDIUM_GRID_C (0x3C7 + LOG_1X_BASE_C) + +/* Static information about the driver or device */ +#define LOG_SNSD_INFO_C (0x3C8 + LOG_1X_BASE_C) + +/* Dynamic state information about the device or driver */ +#define LOG_SNSD_STATE_C (0x3C9 + LOG_1X_BASE_C) + +/* Data from a driver */ +#define LOG_SNSD_DATA (0x3CA + LOG_1X_BASE_C) +#define LOG_SNSD_DATA_C (0x3CA + LOG_1X_BASE_C) + +/* CGPS Cell DB Cell Change Info */ +#define LOG_CGPS_CELLDB_CELL_CHANGE_INFO_C (0x3CB + LOG_1X_BASE_C) + +/* xScalar YUV frame log */ +#define LOG_DEC_XSCALE_YUV_FRAME_C (0x3CC + LOG_1X_BASE_C) + +/* CRC of xScaled YUV frame log */ +#define LOG_DEC_XSCALE_CRC_FRAME_C (0x3CD + LOG_1X_BASE_C) + +/* CGPS Frequency Estimate Report */ +#define LOG_CGPS_FREQ_EST_REPORT_C (0x3CE + LOG_1X_BASE_C) + +/* GPS DCME Srch Job Completed */ +#define LOG_GPS_DCME_SRCH_JOB_COMPLETED_C (0x3CF + LOG_1X_BASE_C) + +/* CGPS ME Fastscan results */ +#define LOG_CGPS_ME_FASTSCAN_RESULTS_C (0x3D0 + LOG_1X_BASE_C) + +/* XO frequency Estimation log */ +#define LOG_XO_FREQ_EST_C (0x3D1 + LOG_1X_BASE_C) + +/* Tcxomgr field calibration data */ +#define LOG_TCXOMGR_FIELD_CAL_C (0x3D2 + LOG_1X_BASE_C) + +/* UMB Call Processing Connection Attempt */ +#define LOG_UMBCP_CONNECTION_ATTEMPT_C (0x3D3 + LOG_1X_BASE_C) + +/* UMB Call Processing Connection Release */ +#define LOG_UMBCP_CONNECTION_RELEASE_C (0x3D4 + LOG_1X_BASE_C) + +/* UMB Call Processing Page Message */ +#define LOG_UMBCP_PAGE_MESSAGE_C (0x3D5 + LOG_1X_BASE_C) + +/* UMB Call Processing OVHD Information */ +#define LOG_UMBCP_OVHD_INFO_C (0x3D6 + LOG_1X_BASE_C) + +/* UMB Call Processing Session Attempt */ +#define LOG_UMBCP_SESSION_ATTEMPT_C (0x3D7 + LOG_1X_BASE_C) + +/* UMB Call Processing Route Information */ +#define LOG_UMBCP_ROUTE_INFO_C (0x3D8 + LOG_1X_BASE_C) + +/* UMB Call Processing State Information */ +#define LOG_UMBCP_STATE_INFO_C (0x3D9 + LOG_1X_BASE_C) + +/* UMB Call Processing SNP */ +#define LOG_UMBCP_SNP_C (0x3DA + LOG_1X_BASE_C) + +/* CGPS Session Early Exit Decision */ +#define LOG_CGPS_SESSION_EARLY_EXIT_DECISION_C (0x3DB + LOG_1X_BASE_C) + +/* GPS RF Linearity Status */ +#define LOG_CGPS_ME_RF_LINEARITY_INFO_C (0x3DC + LOG_1X_BASE_C) + +/* CGPS ME 5ms IQ Sums */ +#define LOG_CGPS_ME_5MS_IQ_SUMS_C (0x3DD + LOG_1X_BASE_C) + +/* CGPS ME 20ms IQ Sums */ +#define LOG_CPGS_ME_20MS_IQ_SUMS_C (0x3DE + LOG_1X_BASE_C) + +/* ROHC Compressor Statistics */ +#define LOG_ROHC_COMPRESSOR_STATS_C (0x3DF + LOG_1X_BASE_C) + +/* ROHC Decompressor Statistics */ +#define LOG_ROHC_DECOMPRESSOR_STATS_C (0x3E0 + LOG_1X_BASE_C) + +/* Sensors - Kalman filter information */ +#define LOG_SENSOR_KF_INFO_C (0x3E1 + LOG_1X_BASE_C) + +/* Sensors - Integrated measurements */ +#define LOG_SENSOR_INT_MEAS_C (0x3E2 + LOG_1X_BASE_C) + +/* Sensors - Bias calibration values */ +#define LOG_SENSOR_BIAS_CALIBRATION_C (0x3E3 + LOG_1X_BASE_C) + +/* Log codes 0x13E4-0x13E7 are not following standard log naming convention */ + +/* DTV ISDB-T Transport Stream Packets */ +#define LOG_DTV_ISDB_TS_PACKETS (0x3E4 + LOG_1X_BASE_C) + +/* DTV ISDB-T PES Packets */ +#define LOG_DTV_ISDB_PES_PACKETS (0x3E5 + LOG_1X_BASE_C) + +/* DTV ISDB-T Sections */ +#define LOG_DTV_ISDB_SECTIONS (0x3E6 + LOG_1X_BASE_C) + +/* DTV ISDB-T Buffering */ +#define LOG_DTV_ISDB_BUFFERING (0x3E7 + LOG_1X_BASE_C) + +/* WLAN System Acquisition and Handoff */ +#define LOG_WLAN_SYS_ACQ_HO_C (0x3E8 + LOG_1X_BASE_C) + +/* WLAN General Configurable Parameters */ +#define LOG_WLAN_GEN_CONFIG_PARAMS_C (0x3E9 + LOG_1X_BASE_C) + +/* UMB Physical Layer Channel and Interference Estimation */ +#define LOG_UMB_PHY_RX_DPICH_CIE_C (0x3EA + LOG_1X_BASE_C) + +/* UMB Physical Layer MMSE/MRC Demodulated Data Symbols (Low) */ +#define LOG_UMB_PHY_RX_DATA_DEMOD_LOW_C (0x3EB + LOG_1X_BASE_C) + +/* UMB Physical Layer MMSE/MRC Demodulated Data Symbols (High) */ +#define LOG_UMB_PHY_RX_DATA_DEMOD_HIGH_C (0x3EC + LOG_1X_BASE_C) + +/* UMB Physical Layer DCH Decoder */ +#define LOG_UMB_PHY_RX_DCH_DECODER_C (0x3ED + LOG_1X_BASE_C) + +/* UMB Physical Layer DCH Statistics */ +#define LOG_UMB_PHY_DCH_STATISTICS_C (0x3EE + LOG_1X_BASE_C) + +/* UMB Physical Layer CqiPich Processing */ +#define LOG_UMB_PHY_RX_CQIPICH_C (0x3EF + LOG_1X_BASE_C) + +/* UMB Physical Layer MIMO/SIMO in CqiPich (High) */ +#define LOG_UMB_PHY_RX_CQIPICH_CHANTAPS_HIGH_C (0x3F0 + LOG_1X_BASE_C) + +/* UMB Physical Layer MIMO/SIMO in CquiPich (Low) */ +#define LOG_UMB_PHY_RX_CQIPICH_CHANTAPS_LOW_C (0x3F1 + LOG_1X_BASE_C) + +/* UMB Physical Layer Time-Domain Channel Taps (High) */ +#define LOG_UMB_PHY_RX_PPICH_CHAN_EST_HIGH_C (0x3F2 + LOG_1X_BASE_C) + +/* UMB Physical Layer Time-Domain Channel Taps (Low) */ +#define LOG_UMB_PHY_RX_PPICH_CHAN_EST_LOW_C (0x3F3 + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator */ +#define LOG_UMB_PHY_TX_PICH_CONFIG_C (0x3F4 + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for R-ACK (High) */ +#define LOG_UMB_PHY_TX_ACK_HIGH_C (0x3F5 + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for R-ACK (Low) */ +#define LOG_UMB_PHY_TX_ACK_LOW_C (0x3F6 + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for R-PICH */ +#define LOG_UMB_PHY_TX_PICH_C (0x3F7 + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for R-ACH (Access) */ +#define LOG_UMB_PHY_TX_ACH_C (0x3F8 + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for R-ODDCCH (High) */ +#define LOG_UMB_PHY_TX_ODCCH_HIGH_C (0x3F9 + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for R-ODDCCH (Low) */ +#define LOG_UMB_PHY_TX_ODCCH_LOW_C (0x3FA + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for R-CDCCH */ +#define LOG_UMB_PHY_TX_RCDCCH_CONFIG_C (0x3FB + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for CQI sent on RCDCCH */ +#define LOG_UMB_PHY_TX_NONFLSS_CQICH_C (0x3FC + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for CQI sent on RCDCCH */ +#define LOG_UMB_PHY_TX_FLSS_CQICH_C (0x3FD + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for PACH sent on RCDCCH */ +#define LOG_UMB_PHY_TX_PAHCH_C (0x3FE + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for REQ sent on RCDCCH */ +#define LOG_UMB_PHY_TX_REQCH_C (0x3FF + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for PSD sent on RCDCCH */ +#define LOG_UMB_PHY_TX_PSDCH_C (0x400 + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for R-DCH */ +#define LOG_UMB_PHY_TX_DCH_C (0x401 + LOG_1X_BASE_C) + +/* UMB Physical Layer Time/Frequency/RxPower Estimate */ +#define LOG_UMB_PHY_RX_TIME_FREQ_POWER_ESTIMATE_C (0x402 + LOG_1X_BASE_C) + +/* UMB Physical Layer FLCS Processing */ +#define LOG_UMB_PHY_RX_FLCS_PROCESSING_C (0x403 + LOG_1X_BASE_C) + +/* UMB Physical Layer PBCCH Processing */ +#define LOG_UMB_PHY_RX_PBCCH_PROCESSING_C (0x404 + LOG_1X_BASE_C) + +/* UMB Physical Layer SBCCH Processing */ +#define LOG_UMB_PHY_RX_SBCCH_PROCESSING_C (0x405 + LOG_1X_BASE_C) + +/* UMB Physical Layer QPCH Processing */ +#define LOG_UMB_PHY_RX_QPCH_PROCESSING_C (0x406 + LOG_1X_BASE_C) + +/* UMB Physical Layer MRC Demodulated Data Symbols (Preamble SBCCH/QPCH) */ +#define LOG_UMB_PHY_RX_SBCCH_DEMOD_C (0x407 + LOG_1X_BASE_C) + +/* UMB Physical Layer MRC Demodulated Data Symbols (Preamble PBCCH) */ +#define LOG_UMB_PHY_RX_PBCCH_DEMOD_C (0x408 + LOG_1X_BASE_C) + +/* UMB Physical Layer VCQI */ +#define LOG_UMB_PHY_RX_VCQI_C (0x409 + LOG_1X_BASE_C) + +/* UMB Physical Layer Acquisition Algorithm */ +#define LOG_UMB_PHY_RX_INITIAL_ACQUISITION_C (0x40A + LOG_1X_BASE_C) + +/* UMB Physical Layer Handoff Search Algorithm */ +#define LOG_UMB_PHY_RX_HANDOFF_SEARCH_C (0x40B + LOG_1X_BASE_C) + +/* UMB RF RFFE Configuration Info */ +#define LOG_UMB_AT_RFFE_CONFG_C (0x40C + LOG_1X_BASE_C) + +/* UMB RF Calibrated Values After Powerup */ +#define LOG_UMB_AT_RFFE_RX_CALIB_C (0x40D + LOG_1X_BASE_C) + +/* UMB RF AGC Block in Acquisition Mode */ +#define LOG_UMB_AT_RFFE_RX_ACQ_C (0x40E + LOG_1X_BASE_C) + +/* UMB RF AGC Block in Idle Mode */ +#define LOG_UMB_AT_RFFE_RX_IDLE_C (0x40F + LOG_1X_BASE_C) + +/* UMB RF AGC Block in Connected Mode */ +#define LOG_UMB_AT_RFFE_RX_CONNECTED_C (0x410 + LOG_1X_BASE_C) + +/* UMB RF AGC Block in Connected Mode (FTM) */ +#define LOG_UMB_AT_RFFE_RX_CONNECTED_FTM_C (0x411 + LOG_1X_BASE_C) + +/* UMB RF Jammer Detector Functionality */ +#define LOG_UMB_AT_RFFE_RX_JAMMER_DETECTOR_FUNCTIONALITY_C (0x412 + LOG_1X_BASE_C) + +/* UMB RF Jammer Detector Response */ +#define LOG_UMB_AT_RFFE_RX_JAMMER_DETECTOR_RESPONSE_C (0x413 + LOG_1X_BASE_C) + +/* UMB RF RFFE TX Power Control */ +#define LOG_UMB_AT_RFFE_TX_BETA_SCALING_C (0x414 + LOG_1X_BASE_C) + +/* UMB Searcher Dump */ +#define LOG_UMB_SEARCHER_DUMP_C (0x415 + LOG_1X_BASE_C) + +/* UMB System Acquire */ +#define LOG_UMB_SYSTEM_ACQUIRE_C (0x416 + LOG_1X_BASE_C) + +/* UMB Set Maintenance */ +#define LOG_UMB_SET_MAINTENANCE_C (0x417 + LOG_1X_BASE_C) + +/* UMB QPCH */ +#define LOG_UMB_QPCH_C (0x418 + LOG_1X_BASE_C) + +/* UMB RLL Forward Partial RP Packet */ +#define LOG_UMB_RLL_FORWARD_PARTIAL_RP_C (0x419 + LOG_1X_BASE_C) + +/* UMB RLL Reverse Partial RP Packet */ +#define LOG_UMB_RLL_REVERSE_PARTIAL_RP_C (0x41A + LOG_1X_BASE_C) + +/* UMB RLL Forward Signal Packet */ +#define LOG_UMB_RLL_FORWARD_SIGNAL_C (0x41B + LOG_1X_BASE_C) + +/* UMB RLL Reverse Signal Packet */ +#define LOG_UMB_RLL_REVERSE_SIGNAL_C (0x41C + LOG_1X_BASE_C) + +/* UMB RLL Forward Statistics */ +#define LOG_UMB_RLL_FORWARD_STATS_C (0x41D + LOG_1X_BASE_C) + +/* UMB RLL Reverse Statistics */ +#define LOG_UMB_RLL_REVERSE_STATS_C (0x41E + LOG_1X_BASE_C) + +/* UMB RLL IRTP */ +#define LOG_UMB_RLL_IRTP_C (0x41F + LOG_1X_BASE_C) + +/* UMB AP Forward Link MAC Packets */ +#define LOG_UMB_AP_FL_MAC_PACKET_C (0x420 + LOG_1X_BASE_C) + +/* UMB AP Reverse Link MAC Packets */ +#define LOG_UMB_AP_RL_MAC_PACKET_C (0x421 + LOG_1X_BASE_C) + +/* GPS Performance Statistics log */ +#define LOG_CGPS_PERFORMANCE_STATS_C (0x422 + LOG_1X_BASE_C) + +/* UMB Searcher General Status */ +#define LOG_UMB_SRCH_GENERAL_STATUS_C (0x423 + LOG_1X_BASE_C) + +/* UMB Superframe Scheduler */ +#define LOG_UMB_SUPERFRAME_SCHEDULER_C (0x424 + LOG_1X_BASE_C) + +/* UMB Sector List */ +#define LOG_UMB_SECTOR_LIST_C (0x425 + LOG_1X_BASE_C) + +/* UMB MAC Access Attempt Command */ +#define LOG_UMB_MAC_ACCESS_ATTEMPT_CMD_C (0x426 + LOG_1X_BASE_C) + +/* UMB MAC Access Probe Information */ +#define LOG_UMB_MAC_ACCESS_PROBE_INFO_C (0x427 + LOG_1X_BASE_C) + +/* UMB MAC RTCMAC Package Information */ +#define LOG_UMB_MAC_RTCMAC_PKG_INFO_C (0x428 + LOG_1X_BASE_C) + +/* UMB MAC Super Frame Information */ +#define LOG_UMB_MAC_SI_INFO_C (0x429 + LOG_1X_BASE_C) + +/* UMB MAC Quick Channel Information */ +#define LOG_UMB_MAC_QCI_INFO_C (0x42A + LOG_1X_BASE_C) + +/* UMB MAC Paging Id List */ +#define LOG_UMB_MAC_PAGING_ID_LIST_C (0x42B + LOG_1X_BASE_C) + +/* UMB MAC Quick Paging Channel Information */ +#define LOG_UMB_MAC_QPCH_INFO_C (0x42C + LOG_1X_BASE_C) + +/* UMB MAC FTCMAC Information */ +#define LOG_UMB_MAC_FTCMAC_PKG_INFO_C (0x42D + LOG_1X_BASE_C) + +/* UMB MAC Access Grant Receiving */ +#define LOG_UMB_MAC_ACCESS_GRANT_C (0x42E + LOG_1X_BASE_C) + +/* UMB MAC Generic Debug Log */ +#define LOG_UMB_MAC_GEN_DEBUG_LOG_PKG_C (0x42F + LOG_1X_BASE_C) + +/* CGPS Frequency Bias Estimate */ +#define LOG_CGPS_MC_FREQ_BIAS_EST_C (0x430 + LOG_1X_BASE_C) + +/* UMB MAC Request Report Information Log */ +#define LOG_UMB_MAC_REQCH_REPORT_INFO_C (0x431 + LOG_1X_BASE_C) + +/* UMB MAC Reverse Link QoS Token Bucket Information Log */ +#define LOG_UMB_MAC_RLQOS_TOKEN_BUCKET_INFO_C (0x432 + LOG_1X_BASE_C) + +/* UMB MAC Reverse Link QoS Stream Information Log */ +#define LOG_UMB_MAC_RLQOS_STREAM_INFO_C (0x433 + LOG_1X_BASE_C) + +/* UMB MAC Reverse Link QoS Allotment Information Log */ +#define LOG_UMB_MAC_RLQOS_ALLOTMENT_INFO_C (0x434 + LOG_1X_BASE_C) + +/* UMB Searcher Recent State Machine Transactions */ +#define LOG_UMB_SRCH_STM_ACTIVITY_C (0x435 + LOG_1X_BASE_C) + +/* Performance Counters on ARM11 Profiling Information */ +#define LOG_ARM11_PERF_CNT_INFO_C (0x436 + LOG_1X_BASE_C) + +/* Protocol Services describe all flow instances */ +#define LOG_PS_STAT_DESC_ALL_FLOW_INST_C (0x437 + LOG_1X_BASE_C) + +/* Protocol Services describe all physical link instances */ +#define LOG_PS_STAT_DESC_ALL_PHYS_LINK_INST_C (0x438 + LOG_1X_BASE_C) + +/* Protocol Services describe all UDP instances */ +#define LOG_PS_STAT_DESC_ALL_UDP_INST_C (0x439 + LOG_1X_BASE_C) + +/* Searcher 4 Multi-Carrier HDR */ +#define LOG_SRCH4_MC_HDR_C (0x43A + LOG_1X_BASE_C) + +/* Protocol Services describe all IPHC instances */ +#define LOG_PS_STAT_DESC_ALL_IPHC_INST_C (0x43B + LOG_1X_BASE_C) + +/* Protocol Services describe all ROHC instances */ +#define LOG_PS_STAT_DESC_ALL_ROHC_INST_C (0x43C + LOG_1X_BASE_C) + +/* BCast security add program information */ +#define LOG_BCAST_SEC_ADD_PROGRAM_INFO_C (0x43D + LOG_1X_BASE_C) + +/* BCast security add program complete */ +#define LOG_BCAST_SEC_ADD_PROGRAM_COMPLETE_C (0x43E + LOG_1X_BASE_C) + +/* BCast security SDP parse */ +#define LOG_BCAST_SEC_SDP_PARSE_C (0x43F + LOG_1X_BASE_C) + +/* CGPS ME dynamic power optimization status */ +#define LOG_CGPS_ME_DPO_STATUS_C (0x440 + LOG_1X_BASE_C) + +/* CGPS PDSM on demand session start */ +#define LOG_CGPS_PDSM_ON_DEMAND_SESSION_START_C (0x441 + LOG_1X_BASE_C) + +/* CGPS PDSM on demand session stop */ +#define LOG_CGPS_PDSM_ON_DEMAND_SESSION_STOP_C (0x442 + LOG_1X_BASE_C) + +/* CGPS PDSM on demand session not started */ +#define LOG_CGPS_PDSM_ON_DEMAND_SESSION_NOT_STARTED_C (0x443 + LOG_1X_BASE_C) + +/* CGPS PDSM extern coarse position inject start */ +#define LOG_CGPS_PDSM_EXTERN_COARSE_POS_INJ_START_C (0x444 + LOG_1X_BASE_C) + +/* DTV ISDB-T TMCC information */ +#define LOG_DTV_ISDB_TMCC_C (0x445 + LOG_1X_BASE_C) + +/* RF development */ +#define LOG_RF_DEV_C (0x446 + LOG_1X_BASE_C) + +/* RF RFM API */ +#define LOG_RF_RFM_API_C (0x447 + LOG_1X_BASE_C) + +/* RF RFM state */ +#define LOG_RF_RFM_STATE_C (0x448 + LOG_1X_BASE_C) + +/* 1X RF Warmup */ +#define LOG_1X_RF_WARMUP_C (0x449 + LOG_1X_BASE_C) + +/* 1X RF power limiting */ +#define LOG_1X_RF_PWR_LMT_C (0x44A + LOG_1X_BASE_C) + +/* 1X RF state */ +#define LOG_1X_RF_STATE_C (0x44B + LOG_1X_BASE_C) + +/* 1X RF sleep */ +#define LOG_1X_RF_SLEEP_C (0x44C + LOG_1X_BASE_C) + +/* 1X RF TX state */ +#define LOG_1X_RF_TX_STATE_C (0x44D + LOG_1X_BASE_C) + +/* 1X RF IntelliCeiver state */ +#define LOG_1X_RF_INT_STATE_C (0x44E + LOG_1X_BASE_C) + +/* 1X RF RX ADC clock */ +#define LOG_1X_RF_RX_ADC_CLK_C (0x44F + LOG_1X_BASE_C) + +/* 1X RF LNA switch point */ +#define LOG_1X_RF_LNA_SWITCHP_C (0x450 + LOG_1X_BASE_C) + +/* 1X RF RX calibration */ +#define LOG_1X_RF_RX_CAL_C (0x451 + LOG_1X_BASE_C) + +/* 1X RF API */ +#define LOG_1X_RF_API_C (0x452 + LOG_1X_BASE_C) + +/* 1X RF RX PLL locking status */ +#define LOG_1X_RF_RX_PLL_LOCK_C (0x453 + LOG_1X_BASE_C) + +/* 1X RF voltage regulator */ +#define LOG_1X_RF_VREG_C (0x454 + LOG_1X_BASE_C) + +/* CGPS DIAG successful fix count */ +#define LOG_CGPS_DIAG_SUCCESSFUL_FIX_COUNT_C (0x455 + LOG_1X_BASE_C) + +/* CGPS MC track dynamic power optimization status */ +#define LOG_CGPS_MC_TRACK_DPO_STATUS_C (0x456 + LOG_1X_BASE_C) + +/* CGPS MC SBAS demodulated bits */ +#define LOG_CGPS_MC_SBAS_DEMOD_BITS_C (0x457 + LOG_1X_BASE_C) + +/* CGPS MC SBAS demodulated soft symbols */ +#define LOG_CGPS_MC_SBAS_DEMOD_SOFT_SYMBOLS_C (0x458 + LOG_1X_BASE_C) + +/* Data Services PPP configuration */ +#define LOG_DS_PPP_CONFIG_PARAMS_C (0x459 + LOG_1X_BASE_C) + +/* Data Services physical link configuration */ +#define LOG_DS_PHYS_LINK_CONFIG_PARAMS_C (0x45A + LOG_1X_BASE_C) + +/* Data Services PPP device configuration */ +#define LOG_PS_PPP_DEV_CONFIG_PARAMS_C (0x45B + LOG_1X_BASE_C) + +/* CGPS PDSM GPS state information */ +#define LOG_CGPS_PDSM_GPS_STATE_INFO_C (0x45C + LOG_1X_BASE_C) + +/* CGPS PDSM EXT status GPS state information */ +#define LOG_CGPS_PDSM_EXT_STATUS_GPS_STATE_INFO_C (0x45D + LOG_1X_BASE_C) + +/* CGPS ME Rapid Search Report */ +#define LOG_CGPS_ME_RAPID_SEARCH_REPORT_C (0x45E + LOG_1X_BASE_C) + +/* CGPS PDSM XTRA-T session */ +#define LOG_CGPS_PDSM_XTRA_T_SESSION_C (0x45F + LOG_1X_BASE_C) + +/* CGPS PDSM XTRA-T upload */ +#define LOG_CGPS_PDSM_XTRA_T_UPLOAD_C (0x460 + LOG_1X_BASE_C) + +/* CGPS Wiper Position Report */ +#define LOG_CGPS_WIPER_POSITION_REPORT_C (0x461 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard HTTP Digest Request Info */ +#define LOG_DTV_DVBH_SEC_SC_HTTP_DIGEST_REQ_C (0x462 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard HTTP Digest Response Info */ +#define LOG_DTV_DVBH_SEC_SC_HTTP_DIGEST_RSP_C (0x463 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard Services Registration Request Info */ +#define LOG_DTV_DVBH_SEC_SC_SVC_REG_REQ_C (0x464 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard Services Registration Complete Info */ +#define LOG_DTV_DVBH_SEC_SC_SVC_REG_COMPLETE_C (0x465 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard Services Deregistration Request Info */ +#define LOG_DTV_DVBH_SEC_SC_SVC_DEREG_REQ_C (0x466 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard Services Deregistration Complete Info */ +#define LOG_DTV_DVBH_SEC_SC_SVC_DEREG_COMPLETE_C (0x467 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard LTKM Request Info */ +#define LOG_DTV_DVBH_SEC_SC_LTKM_REQ_C (0x468 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard LTKM Request Complete Info */ +#define LOG_DTV_DVBH_SEC_SC_LTKM_REQ_COMPLETE_C (0x469 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard Program Selection Info */ +#define LOG_DTV_DVBH_SEC_SC_PROG_SEL_C (0x46A + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard Program Selection Complete Info */ +#define LOG_DTV_DVBH_SEC_SC_PROG_SEL_COMPLETE_C (0x46B + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard LTKM */ +#define LOG_DTV_DVBH_SEC_SC_LTKM_C (0x46C + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard LTKM Verification Message */ +#define LOG_DTV_DVBH_SEC_SC_LTKM_VERIFICATION_C (0x46D + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard Parental Control Message */ +#define LOG_DTV_DVBH_SEC_SC_PARENTAL_CTRL_C (0x46E + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard STKM */ +#define LOG_DTV_DVBH_SEC_SC_STKM_C (0x46F + LOG_1X_BASE_C) + +/* Protocol Services Statistics Global Socket */ +#define LOG_PS_STAT_GLOBAL_SOCK_C (0x470 + LOG_1X_BASE_C) + +/* MCS Application Manager */ +#define LOG_MCS_APPMGR_C (0x471 + LOG_1X_BASE_C) + +/* MCS MSGR */ +#define LOG_MCS_MSGR_C (0x472 + LOG_1X_BASE_C) + +/* MCS QTF */ +#define LOG_MCS_QTF_C (0x473 + LOG_1X_BASE_C) + +/* Sensors Stationary Detector Output */ +#define LOG_STATIONARY_DETECTOR_OUTPUT_C (0x474 + LOG_1X_BASE_C) + +/* Print out the ppm data portion */ +#define LOG_CGPS_PDSM_EXT_STATUS_MEAS_REPORT_PPM_C (0x475 + LOG_1X_BASE_C) + +/* GNSS Position Report */ +#define LOG_GNSS_POSITION_REPORT_C (0x476 + LOG_1X_BASE_C) + +/* GNSS GPS Measurement Report */ +#define LOG_GNSS_GPS_MEASUREMENT_REPORT_C (0x477 + LOG_1X_BASE_C) + +/* GNSS Clock Report */ +#define LOG_GNSS_CLOCK_REPORT_C (0x478 + LOG_1X_BASE_C) + +/* GNSS Demod Soft Decision */ +#define LOG_GNSS_DEMOD_SOFT_DECISIONS_C (0x479 + LOG_1X_BASE_C) + +/* GNSS ME 5MS IQ sum */ +#define LOG_GNSS_ME_5MS_IQ_SUMS_C (0x47A + LOG_1X_BASE_C) + +/* GNSS CD DB report */ +#define LOG_GNSS_CD_DB_REPORT_C (0x47B + LOG_1X_BASE_C) + +/* GNSS PE WLS position report */ +#define LOG_GNSS_PE_WLS_POSITION_REPORT_C (0x47C + LOG_1X_BASE_C) + +/* GNSS PE KF position report */ +#define LOG_GNSS_PE_KF_POSITION_REPORT_C (0x47D + LOG_1X_BASE_C) + +/* GNSS PRX RF HW status report */ +#define LOG_GNSS_PRX_RF_HW_STATUS_REPORT_C (0x47E + LOG_1X_BASE_C) + +/* GNSS DRX RF HW status report */ +#define LOG_GNSS_DRX_RF_HW_STATUS_REPORT_C (0x47F + LOG_1X_BASE_C) + +/* GNSS Glonass Measurement report */ +#define LOG_GNSS_GLONASS_MEASUREMENT_REPORT_C (0x480 + LOG_1X_BASE_C) + +/* GNSS GPS HBW RXD measurement */ +#define LOG_GNSS_GPS_HBW_RXD_MEASUREMENT_C (0x481 + LOG_1X_BASE_C) + +/* GNSS PDSM position report callback */ +#define LOG_GNSS_PDSM_POSITION_REPORT_CALLBACK_C (0x482 + LOG_1X_BASE_C) + +/* ISense Request String */ +#define LOG_ISENSE_REQUEST_STR_C (0x483 + LOG_1X_BASE_C) + +/* ISense Response String */ +#define LOG_ISENSE_RESPONSE_STR_C (0x484 + LOG_1X_BASE_C) + +/* Bluetooth SOC General Log Packet*/ +#define LOG_BT_SOC_GENERAL_C (0x485 + LOG_1X_BASE_C) + +/* QCRil Call Flow */ +#define LOG_QCRIL_CALL_FLOW_C (0x486 + LOG_1X_BASE_C) + +/* CGPS Wideband FFT stats */ +#define LOG_CGPS_WB_FFT_STATS_C (0x487 + LOG_1X_BASE_C) + +/* CGPS Slow Clock Calibration Report*/ +#define LOG_CGPS_SLOW_CLOCK_CALIB_REPORT_C (0x488 + LOG_1X_BASE_C) + +/* SNS GPS TIMESTAMP */ +#define LOG_SNS_GPS_TIMESTAMP_C (0x489 + LOG_1X_BASE_C) + +/* GNSS Search Strategy Task Allocation */ +#define LOG_GNSS_SEARCH_STRATEGY_TASK_ALLOCATION_C (0x48A + LOG_1X_BASE_C) + +/* RF MC STM state */ +#define LOG_1XHDR_MC_STATE_C (0x48B + LOG_1X_BASE_C) + +/* Record in the Sparse Network DB */ +#define LOG_CGPS_SNDB_RECORD_C (0x48C + LOG_1X_BASE_C) + +/* Record removed from the DB */ +#define LOG_CGPS_SNDB_REMOVE_C (0x48D + LOG_1X_BASE_C) + +/* CGPS Reserved */ +#define LOG_GNSS_CC_PERFORMANCE_STATS_C (0x48E + LOG_1X_BASE_C) + +/* GNSS PDSM Set Paramerters */ +#define LOG_GNSS_PDSM_SET_PARAMETERS_C (0x48F + LOG_1X_BASE_C) + +/* GNSS PDSM PD Event Callback */ +#define LOG_GNSS_PDSM_PD_EVENT_CALLBACK_C (0x490 + LOG_1X_BASE_C) + +/* GNSS PDSM PA Event Callback */ +#define LOG_GNSS_PDSM_PA_EVENT_CALLBACK_C (0x491 + LOG_1X_BASE_C) + +/* CGPS Reserved */ +#define LOG_CGPS_RESERVED2_C (0x492 + LOG_1X_BASE_C) + +/* CGPS Reserved */ +#define LOG_CGPS_RESERVED3_C (0x493 + LOG_1X_BASE_C) + +/* GNSS PDSM EXT Status MEAS Report */ +#define LOG_GNSS_PDSM_EXT_STATUS_MEAS_REPORT_C (0x494 + LOG_1X_BASE_C) + +/* GNSS SM Error */ +#define LOG_GNSS_SM_ERROR_C (0x495 + LOG_1X_BASE_C) + +/* WLAN Scan */ +#define LOG_WLAN_SCAN_C (0x496 + LOG_1X_BASE_C) + +/* WLAN IBSS */ +#define LOG_WLAN_IBSS_C (0x497 + LOG_1X_BASE_C) + +/* WLAN 802.11d*/ +#define LOG_WLAN_80211D_C (0x498 + LOG_1X_BASE_C) + +/* WLAN Handoff */ +#define LOG_WLAN_HANDOFF_C (0x499 + LOG_1X_BASE_C) + +/* WLAN QoS EDCA */ +#define LOG_WLAN_QOS_EDCA_C (0x49A + LOG_1X_BASE_C) + +/* WLAN Beacon Update */ +#define LOG_WLAN_BEACON_UPDATE_C (0x49B + LOG_1X_BASE_C) + +/* WLAN Power save wow add pattern */ +#define LOG_WLAN_POWERSAVE_WOW_ADD_PTRN_C (0x49C + LOG_1X_BASE_C) + +/* WLAN WCM link metrics */ +#define LOG_WLAN_WCM_LINKMETRICS_C (0x49D + LOG_1X_BASE_C) + +/* WLAN wps scan complete*/ +#define LOG_WLAN_WPS_SCAN_COMPLETE_C (0x49E + LOG_1X_BASE_C) + +/* WLAN WPS WSC Message */ +#define LOG_WLAN_WPS_WSC_MESSAGE_C (0x49F + LOG_1X_BASE_C) + +/* WLAN WPS credentials */ +#define LOG_WLAN_WPS_CREDENTIALS_C (0x4A0 + LOG_1X_BASE_C) + +/* WLAN Qos TSpec*/ +#define LOG_WLAN_QOS_TSPEC_C (0x4A2 + LOG_1X_BASE_C) + +/* PMIC Vreg Control */ +#define LOG_PM_VREG_CONTROL_C (0x4A3 + LOG_1X_BASE_C) + +/* PMIC Vreg Level */ +#define LOG_PM_VREG_LEVEL_C (0x4A4 + LOG_1X_BASE_C) + +/* PMIC Vreg State */ +#define LOG_PM_VREG_STATE_C (0x4A5 + LOG_1X_BASE_C) + +/* CGPS SM EPH Randomization info */ +#define LOG_CGPS_SM_EPH_RANDOMIZATION_INFO_C (0x4A6 + LOG_1X_BASE_C) + +/* Audio calibration data */ +#define LOG_QACT_DATA_C (0x4A7 + LOG_1X_BASE_C) + +/* Compass 2D Tracked Calibration Set */ +#define LOG_SNS_VCPS_2D_TRACKED_CAL_SET (0x4A8 + LOG_1X_BASE_C) + +/* Compass 3D Tracked Calibration Set */ +#define LOG_SNS_VCPS_3D_TRACKED_CAL_SET (0x4A9 + LOG_1X_BASE_C) + +/* Calibration metric */ +#define LOG_SNS_VCPS_CAL_METRIC (0x4AA + LOG_1X_BASE_C) + +/* Accelerometer distance */ +#define LOG_SNS_VCPS_ACCEL_DIST (0x4AB + LOG_1X_BASE_C) + +/* Plane update */ +#define LOG_SNS_VCPS_PLANE_UPDATE (0x4AC + LOG_1X_BASE_C) + +/* Location report */ +#define LOG_SNS_VCPS_LOC_REPORT (0x4AD + LOG_1X_BASE_C) + +/* CM Active subscription */ +#define LOG_CM_PH_EVENT_SUBSCRIPTION_PREF_INFO_C (0x4AE + LOG_1X_BASE_C) + +/* DSDS version of CM call event */ +#define LOG_CM_DS_CALL_EVENT_C (0x4AF + LOG_1X_BASE_C) + +/* Sensors ?MobiSens Output */ +#define LOG_MOBISENS_OUTPUT_C (0x4B0 + LOG_1X_BASE_C) + +/* Accelerometer Data */ +#define LOG_ACCEL_DATA_C (0x4B1 + LOG_1X_BASE_C) + +/* Accelerometer Compensated Data */ +#define LOG_ACCEL_COMP_DATA_C (0x4B2 + LOG_1X_BASE_C) + +/* Motion State Data */ +#define LOG_MOTION_STATE_DATA_C (0x4B3 + LOG_1X_BASE_C) + +/* Stationary Position Indicator */ +#define LOG_STAT_POS_IND_C (0x4B4 + LOG_1X_BASE_C) + +/* Motion State Features */ +#define LOG_MOTION_STATE_FEATURES_C (0x4B5 + LOG_1X_BASE_C) + +/* Motion State Hard Decision */ +#define LOG_MOTION_STATE_HARD_DECISION_C (0x4B6 + LOG_1X_BASE_C) + +/* Motion State Soft Decision */ +#define LOG_MOTION_STATE_SOFT_DECISION_C (0x4B7 + LOG_1X_BASE_C) + +/* Sensors Software Version */ +#define LOG_SENSORS_SOFTWARE_VERSION_C (0x4B8 + LOG_1X_BASE_C) + +/* MobiSens Stationary Position Indicator Log Packet */ +#define LOG_MOBISENS_SPI_C (0x4B9 + LOG_1X_BASE_C) + +/* XO calibration raw IQ data */ +#define LOG_XO_IQ_DATA_C (0x4BA + LOG_1X_BASE_C) + +/*DTV CMMB Control Tabl Updated*/ +#define LOG_DTV_CMMB_CONTROL_TABLE_UPDATE ((0x4BB) + LOG_1X_BASE_C) + +/*DTV CMMB Media API Buffering Status*/ +#define LOG_DTV_CMMB_MEDIA_BUFFERING_STATUS ((0x4BC) + LOG_1X_BASE_C) + +/*DTV CMMB *Emergency Broadcast Data*/ +#define LOG_DTV_CMMB_CONTROL_EMERGENCY_BCAST ((0x4BD) + LOG_1X_BASE_C) + +/*DTV CMMB EMM/ECM Data*/ +#define LOG_DTV_CMMB_CAS_EMM_ECM ((0x4BE) + LOG_1X_BASE_C) + +/*DTV CMMB HW Status*/ +#define LOG_DTV_CMMB_HW_PERFORMANCE ((0x4BF) + LOG_1X_BASE_C) + +/*DTV CMMB ESSG Program Indication Information*/ +#define LOG_DTV_CMMB_ESG_PROGRAM_INDICATION_INFORMATION ((0x4C0) + LOG_1X_BASE_C) + +/* Sensors ¨C binary output of converted sensor data */ +#define LOG_CONVERTED_SENSOR_DATA_C ((0x4C1) + LOG_1X_BASE_C) + +/* CM Subscription event */ +#define LOG_CM_SUBSCRIPTION_EVENT_C ((0x4C2) + LOG_1X_BASE_C) + +/* Sensor Ambient Light Data */ +#define LOG_SNS_ALS_DATA_C ((0x4C3) + LOG_1X_BASE_C) + +/*Sensor Ambient Light Adaptive Data */ +#define LOG_SNS_ALS_DATA_ADAPTIVE_C ((0x4C4) + LOG_1X_BASE_C) + +/*Sensor Proximity Distance Data */ +#define LOG_SNS_PRX_DIST_DATA_C ((0x4C5) + LOG_1X_BASE_C) + +/*Sensor Proximity Data */ +#define LOG_SNS_PRX_DATA_C ((0x4C6) + LOG_1X_BASE_C) + +#define LOG_GNSS_SBAS_REPORT_C ((0x4C7) + LOG_1X_BASE_C) + +#define LOG_CPU_MONITOR_MODEM_C ((0x4C8) + LOG_1X_BASE_C) + +#define LOG_CPU_MONITOR_APPS_C ((0x4C9) + LOG_1X_BASE_C) + +#define LOG_BLAST_TASKPROFILE_C ((0x4CA) + LOG_1X_BASE_C) + +#define LOG_BLAST_SYSPROFILE_C ((0x4CB) + LOG_1X_BASE_C) + +#define LOG_FM_RADIO_FTM_C ((0x4CC) + LOG_1X_BASE_C) + +#define LOG_FM_RADIO_C ((0x4CD) + LOG_1X_BASE_C) + +#define LOG_UIM_DS_DATA_C ((0x4CE) + LOG_1X_BASE_C) + +#define LOG_QMI_CALL_FLOW_C ((0x4CF) + LOG_1X_BASE_C) + +#define LOG_APR_MODEM_C ((0x4D0) + LOG_1X_BASE_C) + +#define LOG_APR_APPS_C ((0x4D1) + LOG_1X_BASE_C) + +#define LOG_APR_ADSP_C ((0x4D2) + LOG_1X_BASE_C) + +#define LOG_DATA_MUX_RX_RAW_PACKET_C ((0x4D3) + LOG_1X_BASE_C) + +#define LOG_DATA_MUX_TX_RAW_PACKET_C ((0x4D4) + LOG_1X_BASE_C) + +#define LOG_DATA_MUX_RX_FRAME_PACKET_C ((0x4D5) + LOG_1X_BASE_C) + +#define LOG_DATA_MUX_TX_FRAME_PACKET_C ((0x4D6) + LOG_1X_BASE_C) + +#define LOG_CGPS_PDSM_EXT_STATUS_POS_INJ_REQ_INFO_C ((0x4D7) + LOG_1X_BASE_C) + +#define LOG_TEMPERATURE_MONITOR_C ((0x4D8) + LOG_1X_BASE_C) + +#define LOG_SNS_GESTURES_REST_DETECT_C ((0x4D9) + LOG_1X_BASE_C) + +#define LOG_SNS_GESTURES_ORIENTATION_C ((0x4DA) + LOG_1X_BASE_C) + +#define LOG_SNS_GESTURES_FACING_C ((0x4DB) + LOG_1X_BASE_C) + +#define LOG_SNS_GESTURES_BASIC_C ((0x4DC) + LOG_1X_BASE_C) + +#define LOG_SNS_GESTURES_HINBYE_C ((0x4DD) + LOG_1X_BASE_C) + +#define LOG_GNSS_OEMDRE_MEASUREMENT_REPORT_C ((0x4DE) + LOG_1X_BASE_C) + +#define LOG_GNSS_OEMDRE_POSITION_REPORT_C ((0x4E0) + LOG_1X_BASE_C) + +#define LOG_GNSS_OEMDRE_SVPOLY_REPORT_C ((0x4E1) + LOG_1X_BASE_C) + +#define LOG_GNSS_OEMDRSYNC_C ((0x4E2) + LOG_1X_BASE_C) + +#define LOG_SNS_MGR_EVENT_NOTIFY_C ((0x4E3) + LOG_1X_BASE_C) + +#define LOG_SNS_MGR_EVENT_REGISTER_C ((0x4E4) + LOG_1X_BASE_C) + +#define LOG_GNSS_PDSM_PPM_SESSION_BEGIN_C ((0x4E5) + LOG_1X_BASE_C) + +#define LOG_GNSS_PDSM_PPM_SESSION_PPM_SUSPEND_C ((0x4E6) + LOG_1X_BASE_C) + +#define LOG_GNSS_PDSM_PPM_REPORT_THROTTLED_C ((0x4E7) + LOG_1X_BASE_C) + +#define LOG_GNSS_PDSM_PPM_REPORT_FIRED_C ((0x4E8) + LOG_1X_BASE_C) + +#define LOG_GNSS_PDSM_PPM_SESSION_END_C ((0x4E9) + LOG_1X_BASE_C) + +#define LOG_TRSP_DATA_STALL_C ((0x801) + LOG_1X_BASE_C) + +#define LOG_WLAN_PKT_LOG_INFO_C ((0x8E0) + LOG_1X_BASE_C) + +/* The last defined DMSS log code */ +#define LOG_1X_LAST_C ((0x8E0) + LOG_1X_BASE_C) + +/* This is only here for old (pre equipment ID update) logging code */ +#define LOG_LAST_C (LOG_1X_LAST_C & 0xFFF) + +/* ------------------------------------------------------------------------- + * APPS LOG definition: + * The max number of 16 log codes is assigned for Apps. + * The last apps log code could be 0xB00F. + * Below definition is consolidated from log_codes_apps.h + * ------------------------------------------------------------------------- */ + +/* ======================== APPS Profiling ======================== */ +#define LOG_APPS_SYSPROFILE_C (0x01 + LOG_APPS_BASE_C) +#define LOG_APPS_TASKPROFILE_C (0x02 + LOG_APPS_BASE_C) + +/* The last defined APPS log code */ +/* Change it to (0x02 + LOG_LTE_LAST_C) to allow LTE log codes */ +#define LOG_APPS_LAST_C (0x02 + LOG_LTE_LAST_C) + +/* ------------------------------------------------------------------------- + * Log Equipment IDs. + * The number is represented by 4 bits. + * ------------------------------------------------------------------------- */ +typedef enum { + LOG_EQUIP_ID_OEM = 0, /* 3rd party OEM (licensee) use */ + LOG_EQUIP_ID_1X = 1, /* Traditional 1X line of products */ + LOG_EQUIP_ID_RSVD2 = 2, + LOG_EQUIP_ID_RSVD3 = 3, + LOG_EQUIP_ID_WCDMA = 4, + LOG_EQUIP_ID_GSM = 5, + LOG_EQUIP_ID_LBS = 6, + LOG_EQUIP_ID_UMTS = 7, + LOG_EQUIP_ID_TDMA = 8, + LOG_EQUIP_ID_BOA = 9, + LOG_EQUIP_ID_DTV = 10, + LOG_EQUIP_ID_APPS = 11, + LOG_EQUIP_ID_DSP = 12, + + LOG_EQUIP_ID_LAST_DEFAULT = LOG_EQUIP_ID_DSP +} log_equip_id_enum_type; + +#define LOG_EQUIP_ID_MAX 0xF /* The equipment ID is 4 bits */ + +/* Note that these are the official values and are used by default in + diagtune.h. + */ +#define LOG_EQUIP_ID_0_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_1_LAST_CODE_DEFAULT LOG_1X_LAST_C +#define LOG_EQUIP_ID_2_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_3_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_4_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_5_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_6_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_7_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_8_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_9_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_10_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_11_LAST_CODE_DEFAULT LOG_LTE_LAST_C +#define LOG_EQUIP_ID_12_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_13_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_14_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_15_LAST_CODE_DEFAULT 0 + +#endif /* LOG_CODES_H */ diff --git a/utils/host_diag_log/src/host_diag_log.c b/utils/host_diag_log/src/host_diag_log.c new file mode 100644 index 0000000000..d61cb34602 --- /dev/null +++ b/utils/host_diag_log/src/host_diag_log.c @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*============================================================================ + FILE: host_diag_log.c + + OVERVIEW: This source file contains definitions for WLAN UTIL diag APIs + + DEPENDENCIES: + ============================================================================*/ + +#include "qdf_types.h" +#include "i_host_diag_core_log.h" +#include "host_diag_core_event.h" +#include "wlan_nlink_common.h" +#include "cds_sched.h" +#include "wlan_ptt_sock_svc.h" +#include "wlan_nlink_srv.h" +#include "cds_api.h" +#include "wlan_ps_wow_diag.h" + +#define PTT_MSG_DIAG_CMDS_TYPE (0x5050) + +#define DIAG_TYPE_LOGS (1) +#define DIAG_TYPE_EVENTS (2) + +#define DIAG_SWAP16(A) ((((uint16_t)(A) & 0xff00) >> 8) | (((uint16_t)(A) & 0x00ff) << 8)) + +typedef struct event_report_s { + uint32_t diag_type; + uint16_t event_id; + uint16_t length; +} event_report_t; + +/**--------------------------------------------------------------------------- + + \brief host_diag_log_set_code() - + + This function sets the logging code in the given log record. + + \param - ptr - Pointer to the log header type. + - code - log code. + \return - None + + --------------------------------------------------------------------------*/ + +void host_diag_log_set_code(void *ptr, uint16_t code) +{ + if (ptr) { + /* All log packets are required to start with 'log_header_type' */ + ((log_hdr_type *) ptr)->code = code; + } +} + +/**--------------------------------------------------------------------------- + + \brief host_diag_log_set_length() - + + This function sets the length field in the given log record. + + \param - ptr - Pointer to the log header type. + - length - log length. + + \return - None + + --------------------------------------------------------------------------*/ + +void host_diag_log_set_length(void *ptr, uint16_t length) +{ + if (ptr) { + /* All log packets are required to start with 'log_header_type' */ + ((log_hdr_type *) ptr)->len = (uint16_t) length; + } +} + +/**--------------------------------------------------------------------------- + + \brief host_diag_log_submit() - + + This function sends the log data to the ptt socket app only if it is registered with the driver. + + \param - ptr - Pointer to the log header type. + + \return - None + + --------------------------------------------------------------------------*/ + +void host_diag_log_submit(void *plog_hdr_ptr) +{ + log_hdr_type *pHdr = (log_hdr_type *) plog_hdr_ptr; + tAniHdr *wmsg = NULL; + uint8_t *pBuf; + uint16_t data_len; + uint16_t total_len; + + if (cds_is_load_or_unload_in_progress()) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO, + "%s: Unloading/Loading in Progress. Ignore!!!", + __func__); + return; + } + + if (nl_srv_is_initialized() != 0) + return; + + if (cds_is_multicast_logging()) { + data_len = pHdr->len; + + total_len = sizeof(tAniHdr) + sizeof(uint32_t) + data_len; + + pBuf = (uint8_t *) qdf_mem_malloc(total_len); + + if (!pBuf) { + QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, + "qdf_mem_malloc failed"); + return; + } + + wmsg = (tAniHdr *) pBuf; + wmsg->type = PTT_MSG_DIAG_CMDS_TYPE; + wmsg->length = total_len; + wmsg->length = DIAG_SWAP16(wmsg->length); + pBuf += sizeof(tAniHdr); + + /* Diag Type events or log */ + *(uint32_t *) pBuf = DIAG_TYPE_LOGS; + pBuf += sizeof(uint32_t); + + memcpy(pBuf, pHdr, data_len); + ptt_sock_send_msg_to_app (wmsg, 0, ANI_NL_MSG_PUMAC, + INVALID_PID); + qdf_mem_free((void *)wmsg); + } + return; +} + +/** + * host_diag_log_wlock() - This function is used to send wake lock diag events + * @reason: Reason why the wakelock was taken or released + * @wake_lock_name: Function in which the wakelock was taken or released + * @timeout: Timeout value in case of timed wakelocks + * @status: Status field indicating whether the wake lock was taken/released + * + * This function is used to send wake lock diag events to user space + * + * Return: None + * + */ +void host_diag_log_wlock(uint32_t reason, const char *wake_lock_name, + uint32_t timeout, uint32_t status) +{ + WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, + struct host_event_wlan_wake_lock); + + if ((nl_srv_is_initialized() != 0) || + (cds_is_wakelock_enabled() == false)) + return; + + wlan_diag_event.status = status; + wlan_diag_event.reason = reason; + wlan_diag_event.timeout = timeout; + wlan_diag_event.name_len = strlen(wake_lock_name); + strlcpy(&wlan_diag_event.name[0], + wake_lock_name, + wlan_diag_event.name_len+1); + + WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_WAKE_LOCK); +} + +/**--------------------------------------------------------------------------- + + \brief host_diag_event_report_payload() - + + This function sends the event data to the ptt socket app only if it is + registered with the driver. + + \param - ptr - Pointer to the log header type. + + \return - None + + --------------------------------------------------------------------------*/ + +void host_diag_event_report_payload(uint16_t event_Id, uint16_t length, + void *pPayload) +{ + tAniHdr *wmsg = NULL; + uint8_t *pBuf; + event_report_t *pEvent_report; + uint16_t total_len; + + if (cds_is_load_or_unload_in_progress()) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO, + "%s: Unloading/Loading in Progress. Ignore!!!", + __func__); + return; + } + + if (nl_srv_is_initialized() != 0) + return; + + if (cds_is_multicast_logging()) { + total_len = sizeof(tAniHdr) + sizeof(event_report_t) + length; + + pBuf = (uint8_t *) qdf_mem_malloc(total_len); + + if (!pBuf) { + QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, + "qdf_mem_malloc failed"); + return; + } + wmsg = (tAniHdr *) pBuf; + wmsg->type = PTT_MSG_DIAG_CMDS_TYPE; + wmsg->length = total_len; + wmsg->length = DIAG_SWAP16(wmsg->length); + pBuf += sizeof(tAniHdr); + + pEvent_report = (event_report_t *) pBuf; + pEvent_report->diag_type = DIAG_TYPE_EVENTS; + pEvent_report->event_id = event_Id; + pEvent_report->length = length; + + pBuf += sizeof(event_report_t); + + memcpy(pBuf, pPayload, length); + + if (ptt_sock_send_msg_to_app + (wmsg, 0, ANI_NL_MSG_PUMAC, INVALID_PID) < 0) { + QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_WARN, + "Ptt Socket error sending message to the app!!"); + qdf_mem_free((void *)wmsg); + return; + } + + qdf_mem_free((void *)wmsg); + } + + return; + +} + +/** + * host_log_low_resource_failure() - This function is used to send low + * resource failure event + * @event_sub_type: Reason why the failure was observed + * + * This function is used to send low resource failure events to user space + * + * Return: None + * + */ +void host_log_low_resource_failure(uint8_t event_sub_type) +{ + WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, + struct host_event_wlan_low_resource_failure); + + wlan_diag_event.event_sub_type = event_sub_type; + + WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, + EVENT_WLAN_LOW_RESOURCE_FAILURE); +} + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +/** + * qdf_wow_wakeup_host_event()- send wow wakeup event + * @wow_wakeup_cause: WOW wakeup reason code + * + * This function sends wow wakeup reason code diag event + * + * Return: void. + */ +void qdf_wow_wakeup_host_event(uint8_t wow_wakeup_cause) +{ + WLAN_HOST_DIAG_EVENT_DEF(wowRequest, + host_event_wlan_powersave_wow_payload_type); + qdf_mem_zero(&wowRequest, sizeof(wowRequest)); + + wowRequest.event_subtype = WLAN_WOW_WAKEUP; + wowRequest.wow_wakeup_cause = wow_wakeup_cause; + WLAN_HOST_DIAG_EVENT_REPORT(&wowRequest, + EVENT_WLAN_POWERSAVE_WOW); +} +#endif diff --git a/utils/host_diag_log/src/i_host_diag_core_event.h b/utils/host_diag_log/src/i_host_diag_core_event.h new file mode 100644 index 0000000000..db8d5e7fdf --- /dev/null +++ b/utils/host_diag_log/src/i_host_diag_core_event.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined(__I_HOST_DIAG_CORE_EVENT_H) +#define __I_HOST_DIAG_CORE_EVENT_H + +/**========================================================================= + + \file i_host_diag_core_event.h + + \brief Android specific definitions for WLAN UTIL DIAG events + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#ifdef FEATURE_WLAN_DIAG_SUPPORT +#include +#endif + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + +void host_diag_event_report_payload(uint16_t event_Id, uint16_t length, + void *pPayload); +/*--------------------------------------------------------------------------- + Allocate an event payload holder + ---------------------------------------------------------------------------*/ +#define WLAN_HOST_DIAG_EVENT_DEF(payload_name, payload_type) \ + payload_type(payload_name) + +/*--------------------------------------------------------------------------- + Report the event + ---------------------------------------------------------------------------*/ +#define WLAN_HOST_DIAG_EVENT_REPORT(payload_ptr, ev_id) \ + do { \ + host_diag_event_report_payload(ev_id, \ + sizeof(*(payload_ptr)), \ + (void *)(payload_ptr)); \ + } while (0) + +#else /* FEATURE_WLAN_DIAG_SUPPORT */ + +#define WLAN_HOST_DIAG_EVENT_DEF(payload_name, payload_type) +#define WLAN_HOST_DIAG_EVENT_REPORT(payload_ptr, ev_id) + +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + +/** + * enum auth_timeout_type - authentication timeout type + * @AUTH_FAILURE_TIMEOUT: auth failure timeout + * @AUTH_RESPONSE_TIMEOUT: auth response timeout + */ +enum auth_timeout_type { + AUTH_FAILURE_TIMEOUT, + AUTH_RESPONSE_TIMEOUT, +}; + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ +#ifdef FEATURE_WLAN_DIAG_SUPPORT +void host_diag_log_wlock(uint32_t reason, const char *wake_lock_name, + uint32_t timeout, uint32_t status); +#else +static inline void host_diag_log_wlock(uint32_t reason, + const char *wake_lock_name, + uint32_t timeout, uint32_t status) +{ + +} +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +void host_log_low_resource_failure(uint8_t event_sub_type); +#else +static inline void host_log_low_resource_failure(uint8_t event_sub_type) +{ + +} +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +void qdf_wow_wakeup_host_event(uint8_t wow_wakeup_cause); +#else +static inline void qdf_wow_wakeup_host_event(uint8_t wow_wakeup_cause) +{ + return; +} +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __I_HOST_DIAG_CORE_EVENT_H */ diff --git a/utils/host_diag_log/src/i_host_diag_core_log.h b/utils/host_diag_log/src/i_host_diag_core_log.h new file mode 100644 index 0000000000..6412172df8 --- /dev/null +++ b/utils/host_diag_log/src/i_host_diag_core_log.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined(__I_HOST_DIAG_CORE_LOG_H) +#define __I_HOST_DIAG_CORE_LOG_H + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +#include +#endif + +/**========================================================================= + + \file i_host_diag_core_event.h + + \brief android-specific definitions for WLAN UTIL DIAG logs + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +/* FIXME To be removed when DIAG support is added. This definiton should be */ +/* picked from log.h file above. */ +typedef struct { + /* Specifies the length, in bytes of the entry, including this header. */ + uint16_t len; + + /* Specifies the log code for the entry */ + uint16_t code; + + /*Time Stamp lo */ + uint32_t ts_lo; + + /*Time Stamp hi */ + uint32_t ts_hi; +} __packed log_hdr_type; + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +void host_diag_log_set_code(void *ptr, uint16_t code); +void host_diag_log_set_length(void *ptr, uint16_t length); +void host_diag_log_set_timestamp(void *plog_hdr_ptr); +void host_diag_log_submit(void *plog_hdr_ptr); + +/*--------------------------------------------------------------------------- + Allocate an event payload holder + ---------------------------------------------------------------------------*/ + +#define WLAN_HOST_DIAG_LOG_ALLOC(payload_ptr, payload_type, log_code) \ + do { \ + payload_ptr = (payload_type *)qdf_mem_malloc(sizeof(payload_type)); \ + if (payload_ptr) { \ + host_diag_log_set_code(payload_ptr, log_code); \ + host_diag_log_set_length(payload_ptr, sizeof(payload_type)); \ + } \ + } while (0) + +/*--------------------------------------------------------------------------- + Report the event + ---------------------------------------------------------------------------*/ +#define WLAN_HOST_DIAG_LOG_REPORT(payload_ptr) \ + do { \ + if (payload_ptr) { \ + host_diag_log_submit(payload_ptr); \ + qdf_mem_free(payload_ptr); \ + } \ + } while (0) + +/*--------------------------------------------------------------------------- + Free the payload + ---------------------------------------------------------------------------*/ +#define WLAN_HOST_DIAG_LOG_FREE(payload_ptr) \ + do { \ + if (payload_ptr) { \ + qdf_mem_free(payload_ptr); \ + } \ + } while (0) + +#else /* FEATURE_WLAN_DIAG_SUPPORT */ + +#define WLAN_HOST_DIAG_LOG_ALLOC(payload_ptr, payload_type, log_code) +#define WLAN_HOST_DIAG_LOG_REPORT(payload_ptr) +#define WLAN_HOST_DIAG_LOG_FREE(payload_ptr) + +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __I_HOST_DIAG_CORE_LOG_H */ diff --git a/utils/logging/inc/wlan_logging_sock_svc.h b/utils/logging/inc/wlan_logging_sock_svc.h new file mode 100644 index 0000000000..9c45023853 --- /dev/null +++ b/utils/logging/inc/wlan_logging_sock_svc.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** +* wlan_logging_sock_svc.h +* +******************************************************************************/ + +#ifndef WLAN_LOGGING_SOCK_SVC_H +#define WLAN_LOGGING_SOCK_SVC_H + +#include +#include +#include +#include + +int wlan_logging_sock_init_svc(void); +int wlan_logging_sock_deinit_svc(void); +int wlan_logging_sock_activate_svc(int log_fe_to_console, int num_buf); +int wlan_logging_sock_deactivate_svc(void); +int wlan_log_to_user(QDF_TRACE_LEVEL log_level, char *to_be_sent, int length); + +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE +void wlan_logging_set_per_pkt_stats(void); +void wlan_logging_set_fw_flush_complete(void); +void wlan_flush_host_logs_for_fatal(void); +#else +static inline void wlan_flush_host_logs_for_fatal(void) +{ +} +static inline void wlan_logging_set_per_pkt_stats(void) +{ +} +static inline void wlan_logging_set_fw_flush_complete(void) +{ +} +#endif /* WLAN_LOGGING_SOCK_SVC_ENABLE */ + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +void wlan_report_log_completion(uint32_t is_fatal, + uint32_t indicator, + uint32_t reason_code); +#else +static inline void wlan_report_log_completion(uint32_t is_fatal, + uint32_t indicator, + uint32_t reason_code) +{ + return; +} + +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + +void wlan_pkt_stats_to_logger_thread(void *pl_hdr, void *pkt_dump, void *data); + +void wlan_deregister_txrx_packetdump(void); +void wlan_register_txrx_packetdump(void); + +#endif /* WLAN_LOGGING_SOCK_SVC_H */ diff --git a/utils/logging/src/wlan_logging_sock_svc.c b/utils/logging/src/wlan_logging_sock_svc.c new file mode 100644 index 0000000000..9e200caf6f --- /dev/null +++ b/utils/logging/src/wlan_logging_sock_svc.c @@ -0,0 +1,1503 @@ +/* + * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** +* wlan_logging_sock_svc.c +* +******************************************************************************/ + +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE +#include +#ifdef CONFIG_MCL +#include +#include +#include "cds_utils.h" +#include "csr_api.h" +#include "wlan_hdd_main.h" +#include "wma.h" +#endif +#include +#include +#include +#include +#include +#include +#include +#include "host_diag_core_log.h" +#include "ol_txrx_api.h" +#include "pktlog_ac.h" + +#define MAX_NUM_PKT_LOG 32 + +/** + * struct tx_status - tx status + * @tx_status_ok: successfully sent + acked + * @tx_status_discard: discard - not sent (congestion control) + * @tx_status_no_ack: no_ack - sent, but no ack + * @tx_status_download_fail: download_fail - + * the host could not deliver the tx frame to the target + * @tx_status_peer_del: peer_del - tx completion for + * alreay deleted peer used for HL case + * + * This enum has tx status types + */ +enum tx_status { + tx_status_ok, + tx_status_discard, + tx_status_no_ack, + tx_status_download_fail, + tx_status_peer_del, +}; + +#ifdef CONFIG_MCL +static uint8_t gtx_count; +static uint8_t grx_count; +#endif + +#define LOGGING_TRACE(level, args ...) \ + QDF_TRACE(QDF_MODULE_ID_HDD, level, ## args) + +/* Global variables */ + +#define ANI_NL_MSG_LOG_TYPE 89 +#define ANI_NL_MSG_READY_IND_TYPE 90 +#define MAX_LOGMSG_LENGTH 4096 +#define MAX_PKTSTATS_LENGTH 2048 +#define MAX_PKTSTATS_BUFF 16 + +#define HOST_LOG_DRIVER_MSG 0x001 +#define HOST_LOG_PER_PKT_STATS 0x002 +#define HOST_LOG_FW_FLUSH_COMPLETE 0x003 +#define DIAG_TYPE_LOGS 1 +#define PTT_MSG_DIAG_CMDS_TYPE 0x5050 + +struct log_msg { + struct list_head node; + unsigned int radio; + unsigned int index; + /* indicates the current filled log length in logbuf */ + unsigned int filled_length; + /* + * Buf to hold the log msg + * tAniHdr + log + */ + char logbuf[MAX_LOGMSG_LENGTH]; +}; + +/** + * struct packet_dump - This data structure contains the + * Tx/Rx packet stats + * @status: Status + * @type: Type + * @driver_ts: driver timestamp + * @fw_ts: fw timestamp + */ +struct packet_dump { + unsigned char status; + unsigned char type; + uint32_t driver_ts; + uint16_t fw_ts; +} __attribute__((__packed__)); + +/** + * struct pkt_stats_msg - This data structure contains the + * pkt stats node for link list + * @node: LinkList node + * @node: Pointer to skb + */ +struct pkt_stats_msg { + struct list_head node; + struct sk_buff *skb; +}; + +struct wlan_logging { + /* Log Fatal and ERROR to console */ + bool log_fe_to_console; + /* Number of buffers to be used for logging */ + int num_buf; + /* Lock to synchronize access to shared logging resource */ + spinlock_t spin_lock; + /* Holds the free node which can be used for filling logs */ + struct list_head free_list; + /* Holds the filled nodes which needs to be indicated to APP */ + struct list_head filled_list; + /* Wait queue for Logger thread */ + wait_queue_head_t wait_queue; + /* Logger thread */ + struct task_struct *thread; + /* Logging thread sets this variable on exit */ + struct completion shutdown_comp; + /* Indicates to logger thread to exit */ + bool exit; + /* Holds number of dropped logs */ + unsigned int drop_count; + /* current logbuf to which the log will be filled to */ + struct log_msg *pcur_node; + /* Event flag used for wakeup and post indication*/ + unsigned long eventFlag; + /* Indicates logger thread is activated */ + bool is_active; + /* Flush completion check */ + bool is_flush_complete; + /* paramaters for pkt stats */ + struct list_head pkt_stat_free_list; + struct list_head pkt_stat_filled_list; + struct pkt_stats_msg *pkt_stats_pcur_node; + unsigned int pkt_stat_drop_cnt; + spinlock_t pkt_stats_lock; + unsigned int pkt_stats_msg_idx; +}; + +static struct wlan_logging gwlan_logging; +static struct log_msg *gplog_msg; +static struct pkt_stats_msg *gpkt_stats_buffers; + +/* PID of the APP to log the message */ +static int gapp_pid = INVALID_PID; + +/* Utility function to send a netlink message to an application + * in user space + */ +static int wlan_send_sock_msg_to_app(tAniHdr *wmsg, int radio, + int src_mod, int pid) +{ + int err = -1; + int payload_len; + int tot_msg_len; + tAniNlHdr *wnl = NULL; + struct sk_buff *skb; + struct nlmsghdr *nlh; + int wmsg_length = wmsg->length; + static int nlmsg_seq; + + if (radio < 0 || radio > ANI_MAX_RADIOS) { + LOGGING_TRACE(QDF_TRACE_LEVEL_ERROR, + "%s: invalid radio id [%d]", __func__, radio); + return -EINVAL; + } + + payload_len = wmsg_length + sizeof(wnl->radio) + sizeof(*wmsg); + tot_msg_len = NLMSG_SPACE(payload_len); + skb = dev_alloc_skb(tot_msg_len); + if (skb == NULL) { + LOGGING_TRACE(QDF_TRACE_LEVEL_ERROR, + "%s: dev_alloc_skb() failed for msg size[%d]", + __func__, tot_msg_len); + return -ENOMEM; + } + nlh = nlmsg_put(skb, pid, nlmsg_seq++, src_mod, payload_len, + NLM_F_REQUEST); + if (NULL == nlh) { + LOGGING_TRACE(QDF_TRACE_LEVEL_ERROR, + "%s: nlmsg_put() failed for msg size[%d]", + __func__, tot_msg_len); + kfree_skb(skb); + return -ENOMEM; + } + + wnl = (tAniNlHdr *) nlh; + wnl->radio = radio; + memcpy(&wnl->wmsg, wmsg, wmsg_length); + + err = nl_srv_ucast(skb, pid, MSG_DONTWAIT); + if (err) + LOGGING_TRACE(QDF_TRACE_LEVEL_INFO, + "%s: Failed sending Msg Type [0x%X] to pid[%d]\n", + __func__, wmsg->type, pid); + return err; +} + +/* Need to call this with spin_lock acquired */ +static int wlan_queue_logmsg_for_app(void) +{ + char *ptr; + int ret = 0; + ptr = &gwlan_logging.pcur_node->logbuf[sizeof(tAniHdr)]; + ptr[gwlan_logging.pcur_node->filled_length] = '\0'; + + *(unsigned short *)(gwlan_logging.pcur_node->logbuf) = + ANI_NL_MSG_LOG_TYPE; + *(unsigned short *)(gwlan_logging.pcur_node->logbuf + 2) = + gwlan_logging.pcur_node->filled_length; + list_add_tail(&gwlan_logging.pcur_node->node, + &gwlan_logging.filled_list); + + if (!list_empty(&gwlan_logging.free_list)) { + /* Get buffer from free list */ + gwlan_logging.pcur_node = + (struct log_msg *)(gwlan_logging.free_list.next); + list_del_init(gwlan_logging.free_list.next); + } else if (!list_empty(&gwlan_logging.filled_list)) { + /* Get buffer from filled list */ + /* This condition will drop the packet from being + * indicated to app + */ + gwlan_logging.pcur_node = + (struct log_msg *)(gwlan_logging.filled_list.next); + ++gwlan_logging.drop_count; + list_del_init(gwlan_logging.filled_list.next); + ret = 1; + } + + /* Reset the current node values */ + gwlan_logging.pcur_node->filled_length = 0; + return ret; +} + +#ifdef QCA_WIFI_3_0_ADRASTEA +/** + * wlan_add_user_log_radio_time_stamp() - add radio, firmware timestamp and + * time stamp in log buffer + * @tbuf: Pointer to time stamp buffer + * @tbuf_sz: Time buffer size + * @ts: Time stamp value + * @radoi: the radio index + * + * For adrastea time stamp is QTIMER raw tick which will be used by cnss_diag + * to convert it into user visible time stamp. In adrstea FW also uses QTIMER + * raw ticks which is needed to synchronize host and fw log time stamps + * + * Also add logcat timestamp so that driver logs and + * logcat logs can be co-related + * + * For discrete solution e.g rome use system tick and convert it into + * seconds.milli seconds + * + * Return: number of characters written in target buffer not including + * trailing '/0' + */ +static int wlan_add_user_log_radio_time_stamp(char *tbuf, size_t tbuf_sz, + uint64_t ts, int radio) +{ + int tlen; + char time_buf[20]; + + qdf_get_time_of_the_day_in_hr_min_sec_usec(time_buf, sizeof(time_buf)); + + tlen = scnprintf(tbuf, tbuf_sz, "R%d: [%.16s][%llu] %s ", radio, + ((in_irq() ? "irq" : in_softirq() ? "soft_irq" : + current->comm)), + ts, time_buf); + return tlen; +} +#else +/** + * wlan_add_user_log_radio_time_stamp() - add radio, firmware timestamp and + * logcat timestamp in log buffer + * @tbuf: Pointer to time stamp buffer + * @tbuf_sz: Time buffer size + * @ts: Time stamp value + * @radio: the radio index + * + * For adrastea time stamp QTIMER raw tick which will be used by cnss_diag + * to convert it into user visible time stamp + * + * Also add logcat timestamp so that driver logs and + * logcat logs can be co-related + * + * For discrete solution e.g rome use system tick and convert it into + * seconds.milli seconds + * + * Return: number of characters written in target buffer not including + * trailing '/0' + */ +static int wlan_add_user_log_radio_time_stamp(char *tbuf, size_t tbuf_sz, + uint64_t ts, int radio) +{ + int tlen; + uint32_t rem; + char time_buf[20]; + + qdf_get_time_of_the_day_in_hr_min_sec_usec(time_buf, sizeof(time_buf)); + + rem = do_div(ts, QDF_MC_TIMER_TO_SEC_UNIT); + tlen = scnprintf(tbuf, tbuf_sz, "R%d: [%.16s][%lu.%06lu] %s ", radio, + ((in_irq() ? "irq" : in_softirq() ? "soft_irq" : + current->comm)), + (unsigned long) ts, + (unsigned long)rem, time_buf); + return tlen; +} +#endif + +int wlan_log_to_user(QDF_TRACE_LEVEL log_level, char *to_be_sent, int length) +{ + /* Add the current time stamp */ + char *ptr; + char tbuf[60]; + int tlen; + int total_log_len; + unsigned int *pfilled_length; + bool wake_up_thread = false; + unsigned long flags; + uint64_t ts; + int radio = 0; + bool log_overflow = false; + +#ifdef CONFIG_MCL + radio = cds_get_radio_index(); +#endif + + if ( +#ifdef CONFIG_MCL + !cds_is_multicast_logging() || +#endif + (radio == -EINVAL) || + (!gwlan_logging.is_active)) { + /* + * This is to make sure that we print the logs to kmsg console + * when no logger app is running. This is also needed to + * log the initial messages during loading of driver where even + * if app is running it will not be able to + * register with driver immediately and start logging all the + * messages. + */ + /* + * R%d: if the radio index is invalid, just post the message + * to console. + * Also the radio index shouldn't happen to be EINVAL, but if + * that happen just print it, so that the logging would be + * aware the cnss_logger is somehow failed. + */ + pr_info("R%d: %s\n", radio, to_be_sent); + return 0; + } + + ts = qdf_get_log_timestamp(); + tlen = wlan_add_user_log_radio_time_stamp(tbuf, sizeof(tbuf), ts, + radio); + + /* 1+1 indicate '\n'+'\0' */ + total_log_len = length + tlen + 1 + 1; + + spin_lock_irqsave(&gwlan_logging.spin_lock, flags); + /* wlan logging svc resources are not yet initialized */ + if (!gwlan_logging.pcur_node) { + spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); + return -EIO; + } + + pfilled_length = &gwlan_logging.pcur_node->filled_length; + + /* Check if we can accomodate more log into current node/buffer */ + if ((MAX_LOGMSG_LENGTH <= (*pfilled_length + + sizeof(tAniNlHdr))) || + ((MAX_LOGMSG_LENGTH - (*pfilled_length + + sizeof(tAniNlHdr))) < total_log_len)) { + wake_up_thread = true; + wlan_queue_logmsg_for_app(); + pfilled_length = &gwlan_logging.pcur_node->filled_length; + } + + ptr = &gwlan_logging.pcur_node->logbuf[sizeof(tAniHdr)]; + + /* Assumption here is that we receive logs which is always less than + * MAX_LOGMSG_LENGTH, where we can accomodate the + * tAniNlHdr + [context][timestamp] + log + * + * Continue and copy logs to the available length and discard the rest. + */ + if (MAX_LOGMSG_LENGTH < (sizeof(tAniNlHdr) + total_log_len)) { + log_overflow = true; + total_log_len = MAX_LOGMSG_LENGTH - sizeof(tAniNlHdr) - 2; + } + + memcpy(&ptr[*pfilled_length], tbuf, tlen); + memcpy(&ptr[*pfilled_length + tlen], to_be_sent, + min(length, (total_log_len - tlen))); + *pfilled_length += tlen + min(length, total_log_len - tlen); + ptr[*pfilled_length] = '\n'; + *pfilled_length += 1; + + spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); + /* + * QDF_ASSERT if complete log was not accomodated into + * the available buffer. + */ + QDF_ASSERT(!log_overflow); + + /* Wakeup logger thread */ + if ((true == wake_up_thread)) { + set_bit(HOST_LOG_DRIVER_MSG, &gwlan_logging.eventFlag); + wake_up_interruptible(&gwlan_logging.wait_queue); + } + + if (gwlan_logging.log_fe_to_console + && ((QDF_TRACE_LEVEL_FATAL == log_level) + || (QDF_TRACE_LEVEL_ERROR == log_level))) { + pr_info("%s %s\n", tbuf, to_be_sent); + } + + return 0; +} + +/** + * pkt_stats_fill_headers() - This function adds headers to skb + * @skb: skb to which headers need to be added + * + * Return: 0 on success or Errno on failure + */ +static int pkt_stats_fill_headers(struct sk_buff *skb) +{ + struct host_log_pktlog_info cds_pktlog; + int cds_pkt_size = sizeof(struct host_log_pktlog_info); + tAniNlHdr msg_header; + int extra_header_len, nl_payload_len; + static int nlmsg_seq; + int diag_type; + + qdf_mem_zero(&cds_pktlog, cds_pkt_size); + cds_pktlog.version = VERSION_LOG_WLAN_PKT_LOG_INFO_C; + cds_pktlog.buf_len = skb->len; + cds_pktlog.seq_no = gwlan_logging.pkt_stats_msg_idx++; +#ifdef CONFIG_MCL + host_diag_log_set_code(&cds_pktlog, LOG_WLAN_PKT_LOG_INFO_C); + host_diag_log_set_length(&cds_pktlog.log_hdr, skb->len + + cds_pkt_size); +#endif + + if (unlikely(skb_headroom(skb) < cds_pkt_size)) { + pr_err("VPKT [%d]: Insufficient headroom, head[%p], data[%p], req[%zu]", + __LINE__, skb->head, skb->data, sizeof(msg_header)); + return -EIO; + } + + qdf_mem_copy(skb_push(skb, cds_pkt_size), + &cds_pktlog, cds_pkt_size); + + if (unlikely(skb_headroom(skb) < sizeof(int))) { + pr_err("VPKT [%d]: Insufficient headroom, head[%p], data[%p], req[%zu]", + __LINE__, skb->head, skb->data, sizeof(int)); + return -EIO; + } + + diag_type = DIAG_TYPE_LOGS; + qdf_mem_copy(skb_push(skb, sizeof(int)), &diag_type, sizeof(int)); + + extra_header_len = sizeof(msg_header.radio) + sizeof(tAniHdr) + + sizeof(struct nlmsghdr); + nl_payload_len = extra_header_len + skb->len; + + msg_header.nlh.nlmsg_type = ANI_NL_MSG_PUMAC; + msg_header.nlh.nlmsg_len = nl_payload_len; + msg_header.nlh.nlmsg_flags = NLM_F_REQUEST; + msg_header.nlh.nlmsg_pid = 0; + msg_header.nlh.nlmsg_seq = nlmsg_seq++; + msg_header.radio = 0; + msg_header.wmsg.type = PTT_MSG_DIAG_CMDS_TYPE; + msg_header.wmsg.length = cpu_to_be16(skb->len); + + if (unlikely(skb_headroom(skb) < sizeof(msg_header))) { + pr_err("VPKT [%d]: Insufficient headroom, head[%p], data[%p], req[%zu]", + __LINE__, skb->head, skb->data, sizeof(msg_header)); + return -EIO; + } + + qdf_mem_copy(skb_push(skb, sizeof(msg_header)), &msg_header, + sizeof(msg_header)); + + return 0; +} + +/** + * pktlog_send_per_pkt_stats_to_user() - This function is used to send the per + * packet statistics to the user + * + * This function is used to send the per packet statistics to the user + * + * Return: Success if the message is posted to user + */ +int pktlog_send_per_pkt_stats_to_user(void) +{ + int ret = -1; + struct pkt_stats_msg *pstats_msg; + unsigned long flags; + struct sk_buff *skb_new = NULL; + static int rate_limit; + bool free_old_skb = false; + + while (!list_empty(&gwlan_logging.pkt_stat_filled_list) + && !gwlan_logging.exit) { + skb_new = dev_alloc_skb(MAX_PKTSTATS_LENGTH); + if (skb_new == NULL) { + if (!rate_limit) { + pr_err("%s: dev_alloc_skb() failed for msg size[%d] drop count = %u\n", + __func__, MAX_LOGMSG_LENGTH, + gwlan_logging.drop_count); + } + rate_limit = 1; + ret = -ENOMEM; + break; + } + + spin_lock_irqsave(&gwlan_logging.pkt_stats_lock, flags); + + pstats_msg = (struct pkt_stats_msg *) + (gwlan_logging.pkt_stat_filled_list.next); + list_del_init(gwlan_logging.pkt_stat_filled_list.next); + spin_unlock_irqrestore(&gwlan_logging.pkt_stats_lock, flags); + + ret = pkt_stats_fill_headers(pstats_msg->skb); + if (ret < 0) { + pr_err("%s failed to fill headers %d\n", __func__, ret); + free_old_skb = true; + goto err; + } + ret = nl_srv_bcast(pstats_msg->skb); + if (ret < 0) { + pr_info("%s: Send Failed %d drop_count = %u\n", + __func__, ret, + ++gwlan_logging.pkt_stat_drop_cnt); + } else { + ret = 0; + } +err: + /* + * Free old skb in case or error before assigning new skb + * to the free list. + */ + if (free_old_skb) + dev_kfree_skb(pstats_msg->skb); + + spin_lock_irqsave(&gwlan_logging.pkt_stats_lock, flags); + pstats_msg->skb = skb_new; + list_add_tail(&pstats_msg->node, + &gwlan_logging.pkt_stat_free_list); + spin_unlock_irqrestore(&gwlan_logging.pkt_stats_lock, flags); + ret = 0; + } + + return ret; + +} + +static int send_filled_buffers_to_user(void) +{ + int ret = -1; + struct log_msg *plog_msg; + int payload_len; + int tot_msg_len; + tAniNlHdr *wnl; + struct sk_buff *skb = NULL; + struct nlmsghdr *nlh; + static int nlmsg_seq; + unsigned long flags; + static int rate_limit; + + while (!list_empty(&gwlan_logging.filled_list) + && !gwlan_logging.exit) { + + skb = dev_alloc_skb(MAX_LOGMSG_LENGTH); + if (skb == NULL) { + if (!rate_limit) { + pr_err + ("%s: dev_alloc_skb() failed for msg size[%d] drop count = %u\n", + __func__, MAX_LOGMSG_LENGTH, + gwlan_logging.drop_count); + } + rate_limit = 1; + ret = -ENOMEM; + break; + } + rate_limit = 0; + + spin_lock_irqsave(&gwlan_logging.spin_lock, flags); + + plog_msg = (struct log_msg *) + (gwlan_logging.filled_list.next); + list_del_init(gwlan_logging.filled_list.next); + spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); + /* 4 extra bytes for the radio idx */ + payload_len = plog_msg->filled_length + + sizeof(wnl->radio) + sizeof(tAniHdr); + + tot_msg_len = NLMSG_SPACE(payload_len); + nlh = nlmsg_put(skb, 0, nlmsg_seq++, + ANI_NL_MSG_LOG, payload_len, NLM_F_REQUEST); + if (NULL == nlh) { + spin_lock_irqsave(&gwlan_logging.spin_lock, flags); + list_add_tail(&plog_msg->node, + &gwlan_logging.free_list); + spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); + pr_err("%s: drop_count = %u\n", __func__, + ++gwlan_logging.drop_count); + pr_err("%s: nlmsg_put() failed for msg size[%d]\n", + __func__, tot_msg_len); + dev_kfree_skb(skb); + skb = NULL; + ret = -EINVAL; + continue; + } + + wnl = (tAniNlHdr *) nlh; + wnl->radio = plog_msg->radio; + memcpy(&wnl->wmsg, plog_msg->logbuf, + plog_msg->filled_length + sizeof(tAniHdr)); + + spin_lock_irqsave(&gwlan_logging.spin_lock, flags); + list_add_tail(&plog_msg->node, &gwlan_logging.free_list); + spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); + + ret = nl_srv_bcast(skb); + /* print every 64th drop count */ + if (ret < 0 && (!(gwlan_logging.drop_count % 0x40))) { + pr_err("%s: Send Failed %d drop_count = %u\n", + __func__, ret, ++gwlan_logging.drop_count); + skb = NULL; + } else { + skb = NULL; + ret = 0; + } + } + + return ret; +} + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +/** + * wlan_report_log_completion() - Report bug report completion to userspace + * @is_fatal: Type of event, fatal or not + * @indicator: Source of bug report, framework/host/firmware + * @reason_code: Reason for triggering bug report + * + * This function is used to report the bug report completion to userspace + * + * Return: None + */ +void wlan_report_log_completion(uint32_t is_fatal, + uint32_t indicator, + uint32_t reason_code) +{ + WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, + struct host_event_wlan_log_complete); + + wlan_diag_event.is_fatal = is_fatal; + wlan_diag_event.indicator = indicator; + wlan_diag_event.reason_code = reason_code; + wlan_diag_event.reserved = 0; + + WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_LOG_COMPLETE); +} +#endif + +#ifdef CONFIG_MCL +/** + * send_flush_completion_to_user() - Indicate flush completion to the user + * + * This function is used to send the flush completion message to user space + * + * Return: None + */ +static void send_flush_completion_to_user(void) +{ + uint32_t is_fatal, indicator, reason_code; + bool recovery_needed; + + cds_get_and_reset_log_completion(&is_fatal, + &indicator, &reason_code, &recovery_needed); + + /* Error on purpose, so that it will get logged in the kmsg */ + LOGGING_TRACE(QDF_TRACE_LEVEL_ERROR, + "%s: Sending flush done to userspace", __func__); + + wlan_report_log_completion(is_fatal, indicator, reason_code); + + if (recovery_needed) + cds_trigger_recovery(false); +} +#endif + +/** + * wlan_logging_thread() - The WLAN Logger thread + * @Arg - pointer to the HDD context + * + * This thread logs log message to App registered for the logs. + */ +static int wlan_logging_thread(void *Arg) +{ + int ret_wait_status = 0; + int ret = 0; + unsigned long flags; + + set_user_nice(current, -2); + + while (!gwlan_logging.exit) { + ret_wait_status = + wait_event_interruptible(gwlan_logging.wait_queue, + (!list_empty + (&gwlan_logging.filled_list) + || test_bit( + HOST_LOG_DRIVER_MSG, + &gwlan_logging.eventFlag) + || test_bit( + HOST_LOG_PER_PKT_STATS, + &gwlan_logging.eventFlag) + || test_bit( + HOST_LOG_FW_FLUSH_COMPLETE, + &gwlan_logging.eventFlag) + || gwlan_logging.exit)); + + if (ret_wait_status == -ERESTARTSYS) { + pr_err + ("%s: wait_event_interruptible returned -ERESTARTSYS", + __func__); + break; + } + + if (gwlan_logging.exit) + break; + + + if (test_and_clear_bit(HOST_LOG_DRIVER_MSG, + &gwlan_logging.eventFlag)) { + ret = send_filled_buffers_to_user(); + if (-ENOMEM == ret) + msleep(200); +#ifdef CONFIG_MCL + if (WLAN_LOG_INDICATOR_HOST_ONLY == + cds_get_log_indicator()) { + send_flush_completion_to_user(); + } +#endif + } + + if (test_and_clear_bit(HOST_LOG_PER_PKT_STATS, + &gwlan_logging.eventFlag)) { + ret = pktlog_send_per_pkt_stats_to_user(); + if (-ENOMEM == ret) + msleep(200); + } + + if (test_and_clear_bit(HOST_LOG_FW_FLUSH_COMPLETE, + &gwlan_logging.eventFlag)) { + /* Flush bit could have been set while we were mid + * way in the logging thread. So, need to check other + * buffers like log messages, per packet stats again + * to flush any residual data in them + */ + if (gwlan_logging.is_flush_complete == true) { + gwlan_logging.is_flush_complete = false; +#ifdef CONFIG_MCL + send_flush_completion_to_user(); +#endif + } else { + gwlan_logging.is_flush_complete = true; + /* Flush all current host logs*/ + spin_lock_irqsave(&gwlan_logging.spin_lock, + flags); + wlan_queue_logmsg_for_app(); + spin_unlock_irqrestore(&gwlan_logging.spin_lock, + flags); + set_bit(HOST_LOG_DRIVER_MSG, + &gwlan_logging.eventFlag); + set_bit(HOST_LOG_PER_PKT_STATS, + &gwlan_logging.eventFlag); + set_bit(HOST_LOG_FW_FLUSH_COMPLETE, + &gwlan_logging.eventFlag); + wake_up_interruptible( + &gwlan_logging.wait_queue); + } + } + } + + complete_and_exit(&gwlan_logging.shutdown_comp, 0); + + return 0; +} + +/* + * Process all the Netlink messages from Logger Socket app in user space + */ +static int wlan_logging_proc_sock_rx_msg(struct sk_buff *skb) +{ + tAniNlHdr *wnl; + int radio; + int type; + int ret; + + wnl = (tAniNlHdr *) skb->data; + radio = wnl->radio; + type = wnl->nlh.nlmsg_type; + + if (radio < 0 || radio > ANI_MAX_RADIOS) { + LOGGING_TRACE(QDF_TRACE_LEVEL_ERROR, + "%s: invalid radio id [%d]\n", __func__, radio); + return -EINVAL; + } + + if (gapp_pid != INVALID_PID) { + if (wnl->nlh.nlmsg_pid > gapp_pid) { + gapp_pid = wnl->nlh.nlmsg_pid; + } + + spin_lock_bh(&gwlan_logging.spin_lock); + if (gwlan_logging.pcur_node->filled_length) { + wlan_queue_logmsg_for_app(); + } + spin_unlock_bh(&gwlan_logging.spin_lock); + set_bit(HOST_LOG_DRIVER_MSG, &gwlan_logging.eventFlag); + wake_up_interruptible(&gwlan_logging.wait_queue); + } else { + /* This is to set the default levels (WLAN logging + * default values not the QDF trace default) when + * logger app is registered for the first time. + */ + gapp_pid = wnl->nlh.nlmsg_pid; + } + + ret = wlan_send_sock_msg_to_app(&wnl->wmsg, 0, + ANI_NL_MSG_LOG, wnl->nlh.nlmsg_pid); + if (ret < 0) { + LOGGING_TRACE(QDF_TRACE_LEVEL_ERROR, + "wlan_send_sock_msg_to_app: failed"); + } + + return ret; +} + +int wlan_logging_sock_activate_svc(int log_fe_to_console, int num_buf) +{ + int i = 0, j, pkt_stats_size; + unsigned long irq_flag; + + gapp_pid = INVALID_PID; + + gplog_msg = (struct log_msg *)vmalloc(num_buf * sizeof(struct log_msg)); + if (!gplog_msg) { + pr_err("%s: Could not allocate memory\n", __func__); + return -ENOMEM; + } + + qdf_mem_zero(gplog_msg, (num_buf * sizeof(struct log_msg))); + + gwlan_logging.log_fe_to_console = !!log_fe_to_console; + gwlan_logging.num_buf = num_buf; + + spin_lock_irqsave(&gwlan_logging.spin_lock, irq_flag); + INIT_LIST_HEAD(&gwlan_logging.free_list); + INIT_LIST_HEAD(&gwlan_logging.filled_list); + + for (i = 0; i < num_buf; i++) { + list_add(&gplog_msg[i].node, &gwlan_logging.free_list); + gplog_msg[i].index = i; + } + gwlan_logging.pcur_node = (struct log_msg *) + (gwlan_logging.free_list.next); + list_del_init(gwlan_logging.free_list.next); + spin_unlock_irqrestore(&gwlan_logging.spin_lock, irq_flag); + + /* Initialize the pktStats data structure here */ + pkt_stats_size = sizeof(struct pkt_stats_msg); + gpkt_stats_buffers = vmalloc(MAX_PKTSTATS_BUFF * pkt_stats_size); + if (!gpkt_stats_buffers) { + pr_err("%s: Could not allocate memory for Pkt stats\n", + __func__); + goto err1; + } + qdf_mem_zero(gpkt_stats_buffers, + MAX_PKTSTATS_BUFF * pkt_stats_size); + + spin_lock_irqsave(&gwlan_logging.pkt_stats_lock, irq_flag); + gwlan_logging.pkt_stats_msg_idx = 0; + INIT_LIST_HEAD(&gwlan_logging.pkt_stat_free_list); + INIT_LIST_HEAD(&gwlan_logging.pkt_stat_filled_list); + spin_unlock_irqrestore(&gwlan_logging.pkt_stats_lock, irq_flag); + + + for (i = 0; i < MAX_PKTSTATS_BUFF; i++) { + gpkt_stats_buffers[i].skb = dev_alloc_skb(MAX_PKTSTATS_LENGTH); + if (gpkt_stats_buffers[i].skb == NULL) { + pr_err("%s: Memory alloc failed for skb", __func__); + /* free previously allocated skb and return */ + for (j = 0; j < i ; j++) + dev_kfree_skb(gpkt_stats_buffers[j].skb); + goto err2; + } + spin_lock_irqsave(&gwlan_logging.pkt_stats_lock, irq_flag); + list_add(&gpkt_stats_buffers[i].node, + &gwlan_logging.pkt_stat_free_list); + spin_unlock_irqrestore(&gwlan_logging.pkt_stats_lock, irq_flag); + } + spin_lock_irqsave(&gwlan_logging.pkt_stats_lock, irq_flag); + gwlan_logging.pkt_stats_pcur_node = (struct pkt_stats_msg *) + (gwlan_logging.pkt_stat_free_list.next); + list_del_init(gwlan_logging.pkt_stat_free_list.next); + spin_unlock_irqrestore(&gwlan_logging.pkt_stats_lock, irq_flag); + /* Pkt Stats intialization done */ + + init_waitqueue_head(&gwlan_logging.wait_queue); + gwlan_logging.exit = false; + clear_bit(HOST_LOG_DRIVER_MSG, &gwlan_logging.eventFlag); + clear_bit(HOST_LOG_PER_PKT_STATS, &gwlan_logging.eventFlag); + clear_bit(HOST_LOG_FW_FLUSH_COMPLETE, &gwlan_logging.eventFlag); + init_completion(&gwlan_logging.shutdown_comp); + gwlan_logging.thread = kthread_create(wlan_logging_thread, NULL, + "wlan_logging_thread"); + if (IS_ERR(gwlan_logging.thread)) { + pr_err("%s: Could not Create LogMsg Thread Controller", + __func__); + goto err3; + } + wake_up_process(gwlan_logging.thread); + gwlan_logging.is_active = true; + gwlan_logging.is_flush_complete = false; + + nl_srv_register(ANI_NL_MSG_LOG, wlan_logging_proc_sock_rx_msg); + + return 0; + +err3: + for (i = 0; i < MAX_PKTSTATS_BUFF; i++) { + if (gpkt_stats_buffers[i].skb) + dev_kfree_skb(gpkt_stats_buffers[i].skb); + } +err2: + spin_lock_irqsave(&gwlan_logging.pkt_stats_lock, irq_flag); + gwlan_logging.pkt_stats_pcur_node = NULL; + spin_unlock_irqrestore(&gwlan_logging.pkt_stats_lock, irq_flag); + vfree(gpkt_stats_buffers); + gpkt_stats_buffers = NULL; +err1: + spin_lock_irqsave(&gwlan_logging.spin_lock, irq_flag); + gwlan_logging.pcur_node = NULL; + spin_unlock_irqrestore(&gwlan_logging.spin_lock, irq_flag); + vfree(gplog_msg); + gplog_msg = NULL; + return -ENOMEM; +} + +int wlan_logging_sock_deactivate_svc(void) +{ + unsigned long irq_flag; + int i = 0; + + if (!gplog_msg) + return 0; + + nl_srv_unregister(ANI_NL_MSG_LOG, wlan_logging_proc_sock_rx_msg); + gapp_pid = INVALID_PID; + +#ifdef CONFIG_MCL + INIT_COMPLETION(gwlan_logging.shutdown_comp); +#endif + gwlan_logging.exit = true; + gwlan_logging.is_active = false; +#ifdef CONFIG_MCL + cds_set_multicast_logging(0); +#endif + gwlan_logging.is_flush_complete = false; + clear_bit(HOST_LOG_DRIVER_MSG, &gwlan_logging.eventFlag); + clear_bit(HOST_LOG_PER_PKT_STATS, &gwlan_logging.eventFlag); + clear_bit(HOST_LOG_FW_FLUSH_COMPLETE, &gwlan_logging.eventFlag); + wake_up_interruptible(&gwlan_logging.wait_queue); + wait_for_completion(&gwlan_logging.shutdown_comp); + + spin_lock_irqsave(&gwlan_logging.spin_lock, irq_flag); + gwlan_logging.pcur_node = NULL; + spin_unlock_irqrestore(&gwlan_logging.spin_lock, irq_flag); + vfree(gplog_msg); + gplog_msg = NULL; + + spin_lock_irqsave(&gwlan_logging.pkt_stats_lock, irq_flag); + gwlan_logging.pkt_stats_pcur_node = NULL; + gwlan_logging.pkt_stats_msg_idx = 0; + gwlan_logging.pkt_stat_drop_cnt = 0; + for (i = 0; i < MAX_PKTSTATS_BUFF; i++) { + if (gpkt_stats_buffers[i].skb) + dev_kfree_skb(gpkt_stats_buffers[i].skb); + } + spin_unlock_irqrestore(&gwlan_logging.pkt_stats_lock, irq_flag); + + vfree(gpkt_stats_buffers); + gpkt_stats_buffers = NULL; + + return 0; +} + +int wlan_logging_sock_init_svc(void) +{ + spin_lock_init(&gwlan_logging.spin_lock); + spin_lock_init(&gwlan_logging.pkt_stats_lock); + gapp_pid = INVALID_PID; + gwlan_logging.pcur_node = NULL; + gwlan_logging.pkt_stats_pcur_node = NULL; + + return 0; +} + +int wlan_logging_sock_deinit_svc(void) +{ + gwlan_logging.pcur_node = NULL; + gwlan_logging.pkt_stats_pcur_node = NULL; + gapp_pid = INVALID_PID; + + return 0; +} + +/** + * wlan_logging_set_per_pkt_stats() - This function triggers per packet logging + * + * This function is used to send signal to the logger thread for logging per + * packet stats + * + * Return: None + * + */ +void wlan_logging_set_per_pkt_stats(void) +{ + if (gwlan_logging.is_active == false) + return; + + set_bit(HOST_LOG_PER_PKT_STATS, &gwlan_logging.eventFlag); + wake_up_interruptible(&gwlan_logging.wait_queue); +} + +/* + * wlan_logging_set_fw_flush_complete() - FW log flush completion + * + * This function is used to send signal to the logger thread to indicate + * that the flushing of FW logs is complete by the FW + * + * Return: None + * + */ +void wlan_logging_set_fw_flush_complete(void) +{ + if (gwlan_logging.is_active == false +#ifdef CONFIG_MCL + || !cds_is_fatal_event_enabled() +#endif + ) + return; + + set_bit(HOST_LOG_FW_FLUSH_COMPLETE, &gwlan_logging.eventFlag); + wake_up_interruptible(&gwlan_logging.wait_queue); +} + +/** + * wlan_flush_host_logs_for_fatal() - Flush host logs + * + * This function is used to send signal to the logger thread to + * Flush the host logs + * + * Return: None + */ +void wlan_flush_host_logs_for_fatal(void) +{ + unsigned long flags; + +#ifdef CONFIG_MCL + if (cds_is_log_report_in_progress()) { +#endif + pr_info("%s:flush all host logs Setting HOST_LOG_POST_MASK\n", + __func__); + spin_lock_irqsave(&gwlan_logging.spin_lock, flags); + wlan_queue_logmsg_for_app(); + spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); + set_bit(HOST_LOG_DRIVER_MSG, &gwlan_logging.eventFlag); + wake_up_interruptible(&gwlan_logging.wait_queue); +#ifdef CONFIG_MCL + } +#endif +} + +/** + * wlan_get_pkt_stats_free_node() - Get the free node for pkt stats + * + * This function is used to get the free node for pkt stats from + * free list/filles list + * + * Return: int + * + */ +static int wlan_get_pkt_stats_free_node(void) +{ + int ret = 0; + + list_add_tail(&gwlan_logging.pkt_stats_pcur_node->node, + &gwlan_logging.pkt_stat_filled_list); + + if (!list_empty(&gwlan_logging.pkt_stat_free_list)) { + /* Get buffer from free list */ + gwlan_logging.pkt_stats_pcur_node = + (struct pkt_stats_msg *)(gwlan_logging.pkt_stat_free_list.next); + list_del_init(gwlan_logging.pkt_stat_free_list.next); + } else if (!list_empty(&gwlan_logging.pkt_stat_filled_list)) { + /* Get buffer from filled list. This condition will drop the + * packet from being indicated to app + */ + gwlan_logging.pkt_stats_pcur_node = + (struct pkt_stats_msg *) + (gwlan_logging.pkt_stat_filled_list.next); + ++gwlan_logging.pkt_stat_drop_cnt; + /* print every 64th drop count */ + if ( +#ifdef CONFIG_MCL + cds_is_multicast_logging() && +#endif + (!(gwlan_logging.pkt_stat_drop_cnt % 0x40))) { + pr_err("%s: drop_count = %u\n", + __func__, gwlan_logging.pkt_stat_drop_cnt); + } + list_del_init(gwlan_logging.pkt_stat_filled_list.next); + ret = 1; + } + + /* Reset the skb values, essential if dequeued from filled list */ + skb_trim(gwlan_logging.pkt_stats_pcur_node->skb, 0); + return ret; +} + +/** + * wlan_pkt_stats_to_logger_thread() - Add the pkt stats to SKB + * @pl_hdr: Pointer to pl_hdr + * @pkt_dump: Pointer to pkt_dump + * @data: Pointer to data + * + * This function adds the pktstats hdr and data to current + * skb node of free list. + * + * Return: None + */ +void wlan_pkt_stats_to_logger_thread(void *pl_hdr, void *pkt_dump, void *data) +{ +#ifdef CONFIG_MCL + struct ath_pktlog_hdr *pktlog_hdr; + struct packet_dump *pkt_stats_dump; + int total_stats_len = 0; + bool wake_up_thread = false; + unsigned long flags; + struct sk_buff *ptr; + int hdr_size; + + pktlog_hdr = (struct ath_pktlog_hdr *)pl_hdr; + + if (pktlog_hdr == NULL) { + pr_err("%s : Invalid pkt_stats_header\n", __func__); + return; + } + + pkt_stats_dump = (struct packet_dump *)pkt_dump; + total_stats_len = sizeof(struct ath_pktlog_hdr) + + pktlog_hdr->size; + + spin_lock_irqsave(&gwlan_logging.pkt_stats_lock, flags); + + if (!gwlan_logging.pkt_stats_pcur_node || (NULL == pkt_stats_dump)) { + spin_unlock_irqrestore(&gwlan_logging.pkt_stats_lock, flags); + return; + } + + /* Check if we can accommodate more log into current node/buffer */ + hdr_size = sizeof(struct host_log_pktlog_info) + + sizeof(tAniNlHdr); + if ((total_stats_len + hdr_size) >= + skb_tailroom(gwlan_logging.pkt_stats_pcur_node->skb)) { + wake_up_thread = true; + wlan_get_pkt_stats_free_node(); + } + + ptr = gwlan_logging.pkt_stats_pcur_node->skb; + qdf_mem_copy(skb_put(ptr, + sizeof(struct ath_pktlog_hdr)), + pktlog_hdr, + sizeof(struct ath_pktlog_hdr)); + + if (pkt_stats_dump) { + qdf_mem_copy(skb_put(ptr, + sizeof(struct packet_dump)), + pkt_stats_dump, + sizeof(struct packet_dump)); + pktlog_hdr->size -= sizeof(struct packet_dump); + } + + if (data) + qdf_mem_copy(skb_put(ptr, + pktlog_hdr->size), + data, pktlog_hdr->size); + + if (pkt_stats_dump->type == STOP_MONITOR) { + wake_up_thread = true; + wlan_get_pkt_stats_free_node(); + } + + spin_unlock_irqrestore(&gwlan_logging.pkt_stats_lock, flags); + + /* Wakeup logger thread */ + if (true == wake_up_thread) { + set_bit(HOST_LOG_PER_PKT_STATS, &gwlan_logging.eventFlag); + wake_up_interruptible(&gwlan_logging.wait_queue); + } +#endif +} + +#ifdef CONFIG_MCL +/** + * driver_hal_status_map() - maps driver to hal + * status + * @status: status to be mapped + * + * This function is used to map driver to hal status + * + * Return: None + * + */ +static void driver_hal_status_map(uint8_t *status) +{ + switch (*status) { + case tx_status_ok: + *status = TX_PKT_FATE_ACKED; + break; + case tx_status_discard: + *status = TX_PKT_FATE_DRV_DROP_OTHER; + break; + case tx_status_no_ack: + *status = TX_PKT_FATE_SENT; + break; + case tx_status_download_fail: + *status = TX_PKT_FATE_FW_QUEUED; + break; + default: + *status = TX_PKT_FATE_DRV_DROP_OTHER; + break; + } +} + + +/* + * send_packetdump() - send packet dump + * @netbuf: netbuf + * @status: status of tx packet + * @vdev_id: virtual device id + * @type: type of packet + * + * This function is used to send packet dump to HAL layer + * using wlan_pkt_stats_to_logger_thread + * + * Return: None + * + */ +static void send_packetdump(qdf_nbuf_t netbuf, uint8_t status, + uint8_t vdev_id, uint8_t type) +{ + struct ath_pktlog_hdr pktlog_hdr = {0}; + struct packet_dump pd_hdr = {0}; + hdd_context_t *hdd_ctx; + hdd_adapter_t *adapter; + v_CONTEXT_t vos_ctx; + + vos_ctx = cds_get_global_context(); + if (!vos_ctx) + return; + + hdd_ctx = (hdd_context_t *)cds_get_context(QDF_MODULE_ID_HDD); + if (!hdd_ctx) + return; + + adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id); + if (!adapter) + return; + + /* Send packet dump only for STA interface */ + if (adapter->device_mode != QDF_STA_MODE) + return; + +#if defined(HELIUMPLUS) + pktlog_hdr.flags |= PKTLOG_HDR_SIZE_16; +#endif + + pktlog_hdr.log_type = PKTLOG_TYPE_PKT_DUMP; + pktlog_hdr.size = sizeof(pd_hdr) + netbuf->len; + + pd_hdr.status = status; + pd_hdr.type = type; + pd_hdr.driver_ts = qdf_get_monotonic_boottime(); + + if ((type == TX_MGMT_PKT) || (type == TX_DATA_PKT)) + gtx_count++; + else if ((type == RX_MGMT_PKT) || (type == RX_DATA_PKT)) + grx_count++; + + wlan_pkt_stats_to_logger_thread(&pktlog_hdr, &pd_hdr, netbuf->data); +} + + +/* + * send_packetdump_monitor() - sends start/stop packet dump indication + * @type: type of packet + * + * This function is used to indicate HAL layer to start/stop monitoring + * of packets + * + * Return: None + * + */ +static void send_packetdump_monitor(uint8_t type) +{ + struct ath_pktlog_hdr pktlog_hdr = {0}; + struct packet_dump pd_hdr = {0}; + +#if defined(HELIUMPLUS) + pktlog_hdr.flags |= PKTLOG_HDR_SIZE_16; +#endif + + pktlog_hdr.log_type = PKTLOG_TYPE_PKT_DUMP; + pktlog_hdr.size = sizeof(pd_hdr); + + pd_hdr.type = type; + + LOGGING_TRACE(QDF_TRACE_LEVEL_INFO, + "fate Tx-Rx %s: type: %d", __func__, type); + + wlan_pkt_stats_to_logger_thread(&pktlog_hdr, &pd_hdr, NULL); +} + +/** + * wlan_deregister_txrx_packetdump() - tx/rx packet dump + * deregistration + * + * This function is used to deregister tx/rx packet dump callbacks + * with ol, pe and htt layers + * + * Return: None + * + */ +void wlan_deregister_txrx_packetdump(void) +{ + if (gtx_count || grx_count) { + ol_deregister_packetdump_callback(); + wma_deregister_packetdump_callback(); + send_packetdump_monitor(STOP_MONITOR); + csr_packetdump_timer_stop(); + + gtx_count = 0; + grx_count = 0; + } else + LOGGING_TRACE(QDF_TRACE_LEVEL_INFO, + "%s: deregistered packetdump already", __func__); +} + +/* + * check_txrx_packetdump_count() - function to check + * tx/rx packet dump global counts + * + * This function is used to check global counts of tx/rx + * packet dump functionality. + * + * Return: 1 if either gtx_count or grx_count reached 32 + * 0 otherwise + * + */ +static bool check_txrx_packetdump_count(void) +{ + if (gtx_count == MAX_NUM_PKT_LOG || + grx_count == MAX_NUM_PKT_LOG) { + LOGGING_TRACE(QDF_TRACE_LEVEL_INFO, + "%s gtx_count: %d grx_count: %d deregister packetdump", + __func__, gtx_count, grx_count); + wlan_deregister_txrx_packetdump(); + return 1; + } + return 0; +} + +/* + * tx_packetdump_cb() - tx packet dump callback + * @netbuf: netbuf + * @status: status of tx packet + * @vdev_id: virtual device id + * @type: packet type + * + * This function is used to send tx packet dump to HAL layer + * and deregister packet dump callbacks + * + * Return: None + * + */ +static void tx_packetdump_cb(qdf_nbuf_t netbuf, uint8_t status, + uint8_t vdev_id, uint8_t type) +{ + bool temp; + + temp = check_txrx_packetdump_count(); + if (temp) + return; + + driver_hal_status_map(&status); + send_packetdump(netbuf, status, vdev_id, type); +} + + +/* + * rx_packetdump_cb() - rx packet dump callback + * @netbuf: netbuf + * @status: status of rx packet + * @vdev_id: virtual device id + * @type: packet type + * + * This function is used to send rx packet dump to HAL layer + * and deregister packet dump callbacks + * + * Return: None + * + */ +static void rx_packetdump_cb(qdf_nbuf_t netbuf, uint8_t status, + uint8_t vdev_id, uint8_t type) +{ + bool temp; + + temp = check_txrx_packetdump_count(); + if (temp) + return; + + send_packetdump(netbuf, status, vdev_id, type); +} + + +/** + * wlan_register_txrx_packetdump() - tx/rx packet dump + * registration + * + * This function is used to register tx/rx packet dump callbacks + * with ol, pe and htt layers + * + * Return: None + * + */ +void wlan_register_txrx_packetdump(void) +{ + ol_register_packetdump_callback(tx_packetdump_cb, + rx_packetdump_cb); + wma_register_packetdump_callback(tx_packetdump_cb, + rx_packetdump_cb); + send_packetdump_monitor(START_MONITOR); + + gtx_count = 0; + grx_count = 0; +} +#endif +#endif /* WLAN_LOGGING_SOCK_SVC_ENABLE */ diff --git a/utils/nlink/inc/wlan_nlink_common.h b/utils/nlink/inc/wlan_nlink_common.h new file mode 100644 index 0000000000..8d3d4e7afc --- /dev/null +++ b/utils/nlink/inc/wlan_nlink_common.h @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + \file wlan_nlink_common.h + + Exports and types for the Netlink Service interface. This header file contains + message types and definitions that is shared between the user space service + (e.g. logging service) and WLAN kernel module. + + ===========================================================================*/ + +#ifndef WLAN_NLINK_COMMON_H__ +#define WLAN_NLINK_COMMON_H__ + +#include +#include + + +/*--------------------------------------------------------------------------- + * External Functions + *-------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + *-------------------------------------------------------------------------*/ +#define WLAN_NL_MAX_PAYLOAD 256 /* maximum size for netlink message */ +#define WLAN_NLINK_PROTO_FAMILY NETLINK_USERSOCK +#define WLAN_NLINK_MCAST_GRP_ID 0x01 + +/*--------------------------------------------------------------------------- + * Type Declarations + *-------------------------------------------------------------------------*/ + +/* + * The following enum defines the target service within WLAN driver for which the + * message is intended for. Each service along with its counterpart + * in the user space, define a set of messages they recognize. + * Each of this message will have an header of type tAniMsgHdr defined below. + * Each Netlink message to/from a kernel module will contain only one + * message which is preceded by a tAniMsgHdr. The maximun size (in bytes) of + * a netlink message is assumed to be MAX_PAYLOAD bytes. + * + * +------------+-------+----------+----------+ + * |Netlink hdr | Align |tAniMsgHdr| msg body | + * +------------+-------+----------|----------+ + */ + +/* Message Types */ +#define WLAN_SVC_FW_CRASHED_IND 0x100 +#define WLAN_SVC_LTE_COEX_IND 0x101 +#define WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND 0x102 +#define WLAN_SVC_DFS_CAC_START_IND 0x103 +#define WLAN_SVC_DFS_CAC_END_IND 0x104 +#define WLAN_SVC_DFS_RADAR_DETECT_IND 0x105 +#define WLAN_SVC_WLAN_STATUS_IND 0x106 +#define WLAN_SVC_WLAN_VERSION_IND 0x107 +#define WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND 0x108 +#define WLAN_SVC_WLAN_TP_IND 0x109 +#define WLAN_SVC_RPS_ENABLE_IND 0x10A +#define WLAN_SVC_WLAN_TP_TX_IND 0x10B +#define WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND 0x10C +#define WLAN_SVC_WLAN_RADIO_INDEX 0x10D +#define WLAN_SVC_FW_SHUTDOWN_IND 0x10E +#define WLAN_SVC_MAX_SSID_LEN 32 +#define WLAN_SVC_MAX_BSSID_LEN 6 +#define WLAN_SVC_MAX_STR_LEN 16 +#define WLAN_SVC_MAX_NUM_CHAN 128 +#define WLAN_SVC_COUNTRY_CODE_LEN 3 + +#define ANI_NL_MSG_BASE 0x10 /* Some arbitrary base */ + +typedef enum eAniNlModuleTypes { + ANI_NL_MSG_PUMAC = ANI_NL_MSG_BASE + 0x01, /* PTT Socket App */ + ANI_NL_MSG_PTT = ANI_NL_MSG_BASE + 0x07, /* Quarky GUI */ + WLAN_NL_MSG_OEM = ANI_NL_MSG_BASE + 0x09, + WLAN_NL_MSG_SVC, + WLAN_NL_MSG_CNSS_DIAG = ANI_NL_MSG_BASE + 0x0B, /* Value needs to be 27 */ + ANI_NL_MSG_LOG, + ANI_NL_MSG_MAX +} tAniNlModTypes, tWlanNlModTypes; + +#define WLAN_NL_MSG_BASE ANI_NL_MSG_BASE +#define WLAN_NL_MSG_MAX ANI_NL_MSG_MAX + +/* All Netlink messages must contain this header */ +typedef struct sAniHdr { + unsigned short type; + unsigned short length; +} tAniHdr, tAniMsgHdr; + +typedef struct sAniNlMsg { + struct nlmsghdr nlh; /* Netlink Header */ + int radio; /* unit number of the radio */ + tAniHdr wmsg; /* Airgo Message Header */ +} tAniNlHdr; + +struct radio_index_tlv { + unsigned short type; + unsigned short length; + int radio; +}; + +struct wlan_status_data { + uint8_t lpss_support; + uint8_t is_on; + uint8_t vdev_id; + uint8_t is_connected; + int8_t rssi; + uint8_t ssid_len; + uint8_t country_code[WLAN_SVC_COUNTRY_CODE_LEN]; + uint32_t vdev_mode; + uint32_t freq; + uint32_t numChannels; + uint8_t channel_list[WLAN_SVC_MAX_NUM_CHAN]; + uint8_t ssid[WLAN_SVC_MAX_SSID_LEN]; + uint8_t bssid[WLAN_SVC_MAX_BSSID_LEN]; +}; + +struct wlan_version_data { + uint32_t chip_id; + char chip_name[WLAN_SVC_MAX_STR_LEN]; + char chip_from[WLAN_SVC_MAX_STR_LEN]; + char host_version[WLAN_SVC_MAX_STR_LEN]; + char fw_version[WLAN_SVC_MAX_STR_LEN]; +}; + +struct wlan_dfs_info { + uint16_t channel; + uint8_t country_code[WLAN_SVC_COUNTRY_CODE_LEN]; +}; + +/* + * Maximim number of queues supported by WLAN driver. Setting an upper + * limit. Actual number of queues may be smaller than this value. + */ +#define WLAN_SVC_IFACE_NUM_QUEUES 6 + +/** + * struct wlan_rps_data - structure to send RPS info to cnss-daemon + * @ifname: interface name for which the RPS data belongs to + * @num_queues: number of rx queues for which RPS data is being sent + * @cpu_map_list: array of cpu maps for different rx queues supported by + * the wlan driver + * + * The structure specifies the format of data exchanged between wlan + * driver and cnss-daemon. On receipt of the data, cnss-daemon is expected + * to apply the 'cpu_map' for each rx queue belonging to the interface 'ifname' + */ +struct wlan_rps_data { + char ifname[IFNAMSIZ]; + uint16_t num_queues; + uint16_t cpu_map_list[WLAN_SVC_IFACE_NUM_QUEUES]; +}; + +/** + * enum wlan_tp_level - indicates wlan throughput level + * @WLAN_SVC_TP_NONE: used for initialization + * @WLAN_SVC_TP_LOW: used to identify low throughput level + * @WLAN_SVC_TP_MEDIUM: used to identify medium throughput level + * @WLAN_SVC_TP_HIGH: used to identify high throughput level + * + * The different throughput levels are determined on the basis of # of tx and + * rx packets and other threshold values. For example, if the # of total + * packets sent or received by the driver is greater than 500 in the last 100ms + * , the driver has a high throughput requirement. The driver may tweak certain + * system parameters based on the throughput level. + */ +enum wlan_tp_level { + WLAN_SVC_TP_NONE, + WLAN_SVC_TP_LOW, + WLAN_SVC_TP_MEDIUM, + WLAN_SVC_TP_HIGH, +}; + +#endif /* WLAN_NLINK_COMMON_H__ */ diff --git a/utils/nlink/inc/wlan_nlink_srv.h b/utils/nlink/inc/wlan_nlink_srv.h new file mode 100644 index 0000000000..85ee49f482 --- /dev/null +++ b/utils/nlink/inc/wlan_nlink_srv.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** +* wlan_nlink_srv.h +* +* wlan_nlink_srv is used to RX/TX Netlink messages from user space to kernel +* modules and vice versa. Kernel modules must register a message handler for a +* message type so that the wlan_nlink_srv can invoke the corresponding msg handler +* whenever a Netlink message of a particular type has been received from an +* application. In the opposite direction, wlan_nlink_srv provides a mechanism +* which kernel modules can use to send Netlink messages to applications. +* +******************************************************************************/ + +#ifndef WLAN_NLINK_SRV_H +#define WLAN_NLINK_SRV_H + +#include +#include +#include + +#define INVALID_PID -1 +#define NLINK_MAX_CALLBACKS (WLAN_NL_MSG_MAX - WLAN_NL_MSG_BASE) + +typedef int (*nl_srv_msg_callback)(struct sk_buff *skb); + +int nl_srv_init(void *wiphy); +void nl_srv_exit(void); +int nl_srv_register(tWlanNlModTypes msg_type, nl_srv_msg_callback msg_handler); +int nl_srv_unregister(tWlanNlModTypes msg_type, + nl_srv_msg_callback msg_handler); +int nl_srv_ucast(struct sk_buff *skb, int dst_pid, int flag); +int nl_srv_bcast(struct sk_buff *skb); +int nl_srv_is_initialized(void); +#endif diff --git a/utils/nlink/src/wlan_nlink_srv.c b/utils/nlink/src/wlan_nlink_srv.c new file mode 100644 index 0000000000..99de5c0d51 --- /dev/null +++ b/utils/nlink/src/wlan_nlink_srv.c @@ -0,0 +1,539 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** +* wlan_nlink_srv.c +* +* This file contains the definitions specific to the wlan_nlink_srv +* +******************************************************************************/ +/* + * If MULTI_IF_NAME is not defined, then this is the primary instance of the + * driver and the diagnostics netlink socket will be available. If + * MULTI_IF_NAME is defined then this is not the primary instance of the driver + * and the diagnotics netlink socket will not be available since this + * diagnostics netlink socket can only be exposed by one instance of the driver. + */ +#ifndef MULTI_IF_NAME + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_CNSS_LOGGER) + +#include + +static int radio_idx = -EINVAL; +static void *wiphy_ptr; +static bool logger_initialized; + +/** + * nl_srv_init() - wrapper function to register to cnss_logger + * @wiphy: the pointer to the wiphy structure + * + * The netlink socket is no longer initialized in the driver itself, instead + * will be initialized in the cnss_logger module, the driver should register + * itself to cnss_logger module to get the radio_index for all the netlink + * operation. (cfg80211 vendor command is using different netlink socket). + * + * The cnss_logger_device_register() use to register the driver with the + * wiphy structure and the module name (debug purpose) and then return the + * radio_index depending on the availibility. + * + * Return: radio index for success and -EINVAL for failure + */ +int nl_srv_init(void *wiphy) +{ + if (logger_initialized) + goto initialized; + + wiphy_ptr = wiphy; + radio_idx = cnss_logger_device_register(wiphy, THIS_MODULE->name); + QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, + "%s: radio_index: %d, wiphy_ptr: %p", + __func__, radio_idx, wiphy_ptr); + + if (radio_idx >= 0) + logger_initialized = true; + +initialized: + return radio_idx; +} + +/** + * nl_srv_exit() - wrapper function to unregister from cnss_logger + * + * The cnss_logger_device_unregister() use to unregister the driver with + * the radio_index assigned and wiphy structure from cnss_logger. + * + * Return: None + */ +void nl_srv_exit(void) +{ + if (logger_initialized) { + cnss_logger_device_unregister(radio_idx, wiphy_ptr); + radio_idx = -EINVAL; + wiphy_ptr = NULL; + logger_initialized = false; + } +} + +/** + * nl_srv_ucast() - wrapper function to do unicast tx through cnss_logger + * @skb: the socket buffer to send + * @dst_pid: the port id + * @flag: the blocking or nonblocking flag + * + * The nl_srv_is_initialized() is used to do sanity check if the netlink + * service is ready, e.g if the radio_index is assigned properly, if not + * the driver should take the responsibility to free the skb. + * + * The cnss_logger_nl_ucast() use the same parameters to send the socket + * buffers. + * + * Return: the error of the transmission status + */ +int nl_srv_ucast(struct sk_buff *skb, int dst_pid, int flag) +{ + int err = -EINVAL; + + /* sender's pid */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)) + NETLINK_CB(skb).pid = 0; +#else + NETLINK_CB(skb).portid = 0; +#endif + /* not multicast */ + NETLINK_CB(skb).dst_group = 0; + + if (nl_srv_is_initialized() == 0) + err = cnss_logger_nl_ucast(skb, dst_pid, flag); + else + dev_kfree_skb(skb); + return err; +} + +/** + * nl_srv_bcast() - wrapper function to do broadcast tx through cnss_logger + * @skb: the socket buffer to send + * + * The cnss_logger_nl_bcast() is used to transmit the socket buffer. + * + * Return: status of transmission + */ +int nl_srv_bcast(struct sk_buff *skb) +{ + int err = -EINVAL; + int flags = GFP_KERNEL; + + if (in_interrupt() || irqs_disabled() || in_atomic()) + flags = GFP_ATOMIC; + + /* sender's pid */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)) + NETLINK_CB(skb).pid = 0; +#else + NETLINK_CB(skb).portid = 0; +#endif + /* destination group */ + NETLINK_CB(skb).dst_group = WLAN_NLINK_MCAST_GRP_ID; + + if (nl_srv_is_initialized() == 0) + err = cnss_logger_nl_bcast(skb, WLAN_NLINK_MCAST_GRP_ID, flags); + else + dev_kfree_skb(skb); + return err; +} + +/** + * nl_srv_unregister() - wrapper function to unregister event to cnss_logger + * @msg_type: the message to unregister + * @msg_handler: the message handler + * + * The cnss_logger_event_unregister() is used to unregister the message and + * message handler. + * + * Return: 0 if successfully unregister, otherwise proper error code + */ +int nl_srv_unregister(tWlanNlModTypes msg_type, nl_srv_msg_callback msg_handler) +{ + int ret = -EINVAL; + + if (nl_srv_is_initialized() != 0) + return ret; + + if ((msg_type >= WLAN_NL_MSG_BASE) && (msg_type < WLAN_NL_MSG_MAX) && + msg_handler != NULL) { + ret = cnss_logger_event_unregister(radio_idx, msg_type, + msg_handler); + } else { + QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, + "NLINK: nl_srv_unregister failed for msg_type %d", + msg_type); + ret = -EINVAL; + } + + return ret; +} + +/** + * nl_srv_register() - wrapper function to register event to cnss_logger + * @msg_type: the message to register + * @msg_handler: the message handler + * + * The cnss_logger_event_register() is used to register the message and + * message handler. + * + * Return: 0 if successfully register, otherwise proper error code + */ +int nl_srv_register(tWlanNlModTypes msg_type, nl_srv_msg_callback msg_handler) +{ + int ret = -EINVAL; + + if (nl_srv_is_initialized() != 0) + return ret; + + if ((msg_type >= WLAN_NL_MSG_BASE) && (msg_type < WLAN_NL_MSG_MAX) && + msg_handler != NULL) { + ret = cnss_logger_event_register(radio_idx, msg_type, + msg_handler); + } else { + QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, + "NLINK: nl_srv_register failed for msg_type %d", + msg_type); + ret = -EINVAL; + } + + return ret; +} + +/** + * nl_srv_is_initialized() - check if netlink service is initialized + * + * Return: 0 if it is initialized, otherwise error code + */ +inline int nl_srv_is_initialized(void) +{ + if (logger_initialized) + return 0; + else + return -EPERM; +} + +#else + + +/* Global variables */ +static DEFINE_MUTEX(nl_srv_sem); +static struct sock *nl_srv_sock; +static nl_srv_msg_callback nl_srv_msg_handler[NLINK_MAX_CALLBACKS]; + +/* Forward declaration */ +static void nl_srv_rcv(struct sk_buff *sk); +static void nl_srv_rcv_skb(struct sk_buff *skb); +static void nl_srv_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh); + +/* + * Initialize the netlink service. + * Netlink service is usable after this. + */ +int nl_srv_init(void *wiphy) +{ + int retcode = 0; + struct netlink_kernel_cfg cfg = { + .groups = WLAN_NLINK_MCAST_GRP_ID, + .input = nl_srv_rcv + }; + + nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_PROTO_FAMILY, + &cfg); + + if (nl_srv_sock != NULL) { + memset(nl_srv_msg_handler, 0, sizeof(nl_srv_msg_handler)); + } else { + QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, + "NLINK: netlink_kernel_create failed"); + retcode = -ECONNREFUSED; + } + return retcode; +} + +/* + * Deinit the netlink service. + * Netlink service is unusable after this. + */ +void nl_srv_exit(void) +{ + if (nl_srv_is_initialized() == 0) + netlink_kernel_release(nl_srv_sock); + + nl_srv_sock = NULL; +} + +/* + * Register a message handler for a specified module. + * Each module (e.g. WLAN_NL_MSG_BTC )will register a + * handler to handle messages addressed to it. + */ +int nl_srv_register(tWlanNlModTypes msg_type, nl_srv_msg_callback msg_handler) +{ + int retcode = 0; + + if ((msg_type >= WLAN_NL_MSG_BASE) && (msg_type < WLAN_NL_MSG_MAX) && + msg_handler != NULL) { + nl_srv_msg_handler[msg_type - WLAN_NL_MSG_BASE] = msg_handler; + } else { + QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_WARN, + "NLINK: nl_srv_register failed for msg_type %d", + msg_type); + retcode = -EINVAL; + } + + return retcode; +} + +/* + * Unregister the message handler for a specified module. + */ +int nl_srv_unregister(tWlanNlModTypes msg_type, nl_srv_msg_callback msg_handler) +{ + int retcode = 0; + + if ((msg_type >= WLAN_NL_MSG_BASE) && (msg_type < WLAN_NL_MSG_MAX) && + (nl_srv_msg_handler[msg_type - WLAN_NL_MSG_BASE] == msg_handler)) { + nl_srv_msg_handler[msg_type - WLAN_NL_MSG_BASE] = NULL; + } else { + QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_WARN, + "NLINK: nl_srv_unregister failed for msg_type %d", + msg_type); + retcode = -EINVAL; + } + + return retcode; +} + +/* + * Unicast the message to the process in user space identfied + * by the dst-pid + */ +int nl_srv_ucast(struct sk_buff *skb, int dst_pid, int flag) +{ + int err = 0; + + NETLINK_CB(skb).portid = 0; /* sender's pid */ + NETLINK_CB(skb).dst_group = 0; /* not multicast */ + + if (nl_srv_sock) + err = netlink_unicast(nl_srv_sock, skb, dst_pid, flag); + + if (err < 0) + QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_WARN, + "NLINK: netlink_unicast to pid[%d] failed, ret[%d]", + dst_pid, err); + + return err; +} + +/* + * Broadcast the message. Broadcast will return an error if + * there are no listeners + */ +int nl_srv_bcast(struct sk_buff *skb) +{ + int err = 0; + int flags = GFP_KERNEL; + + if (in_interrupt() || irqs_disabled() || in_atomic()) + flags = GFP_ATOMIC; + + NETLINK_CB(skb).portid = 0; /* sender's pid */ + NETLINK_CB(skb).dst_group = WLAN_NLINK_MCAST_GRP_ID; /* destination group */ + + if (nl_srv_sock) + err = netlink_broadcast(nl_srv_sock, skb, 0, + WLAN_NLINK_MCAST_GRP_ID, flags); + + if ((err < 0) && (err != -ESRCH)) { + QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_WARN, + "NLINK: netlink_broadcast failed err = %d", err); + } + return err; +} + +/* + * Processes the Netlink socket input queue. + * Dequeue skb's from the socket input queue and process + * all the netlink messages in that skb, before moving + * to the next skb. + */ +static void nl_srv_rcv(struct sk_buff *sk) +{ + mutex_lock(&nl_srv_sem); + nl_srv_rcv_skb(sk); + mutex_unlock(&nl_srv_sem); +} + +/* + * Each skb could contain multiple Netlink messages. Process all the + * messages in one skb and discard malformed skb's silently. + */ +static void nl_srv_rcv_skb(struct sk_buff *skb) +{ + struct nlmsghdr *nlh; + + while (skb->len >= NLMSG_SPACE(0)) { + u32 rlen; + + nlh = (struct nlmsghdr *)skb->data; + + if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) { + QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_WARN, + "NLINK: Invalid " + "Netlink message: skb[%p], len[%d], nlhdr[%p], nlmsg_len[%d]", + skb, skb->len, nlh, nlh->nlmsg_len); + return; + } + + rlen = NLMSG_ALIGN(nlh->nlmsg_len); + if (rlen > skb->len) + rlen = skb->len; + nl_srv_rcv_msg(skb, nlh); + skb_pull(skb, rlen); + } +} + +/* + * Process a netlink message. + * Each netlink message will have a message of type tAniMsgHdr inside. + */ +static void nl_srv_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) +{ + int type; + + /* Only requests are handled by kernel now */ + if (!(nlh->nlmsg_flags & NLM_F_REQUEST)) { + QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_WARN, + "NLINK: Received Invalid NL Req type [%x]", + nlh->nlmsg_flags); + return; + } + + type = nlh->nlmsg_type; + + /* Unknown message */ + if (type < WLAN_NL_MSG_BASE || type >= WLAN_NL_MSG_MAX) { + QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_WARN, + "NLINK: Received Invalid NL Msg type [%x]", type); + return; + } + + /* + * All the messages must at least carry the tAniMsgHdr + * Drop any message with invalid length + */ + if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(tAniMsgHdr))) { + QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_WARN, + "NLINK: Received NL Msg with invalid len[%x]", + nlh->nlmsg_len); + return; + } + + /* turn type into dispatch table offset */ + type -= WLAN_NL_MSG_BASE; + + /* dispatch to handler */ + if (nl_srv_msg_handler[type] != NULL) { + (nl_srv_msg_handler[type])(skb); + } else { + QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_WARN, + "NLINK: No handler for Netlink Msg [0x%X]", type); + } +} + +/** + * nl_srv_is_initialized() - This function is used check if the netlink + * service is initialized + * + * This function is used check if the netlink service is initialized + * + * Return: Return -EPERM if the service is not initialized + * + */ +int nl_srv_is_initialized(void) +{ + if (nl_srv_sock) + return 0; + + return -EPERM; +} +#endif +#else /* ifndef MULTI_IF_NAME */ + +#include + +int nl_srv_init(void *wiphy) +{ + return 0; +} + +void nl_srv_exit(void) +{ +} + +int nl_srv_register(tWlanNlModTypes msg_type, nl_srv_msg_callback msg_handler) +{ + return 0; +} + +int nl_srv_unregister(tWlanNlModTypes msg_type, nl_srv_msg_callback msg_handler) +{ + return 0; +} + +int nl_srv_ucast(struct sk_buff *skb, int dst_pid, int flag) +{ + return 0; +} + +int nl_srv_bcast(struct sk_buff *skb) +{ + return 0; +} + +int nl_srv_is_initialized(void) +{ + return 0; +} +#endif diff --git a/utils/pktlog/include/pktlog.h b/utils/pktlog/include/pktlog.h new file mode 100644 index 0000000000..fb4fb60366 --- /dev/null +++ b/utils/pktlog/include/pktlog.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _PKTLOG_ +#define _PKTLOG_ +#ifndef REMOVE_PKT_LOG + +/** + * @typedef ol_pktlog_dev_handle + * @brief opaque handle for pktlog device object + */ +struct ol_pktlog_dev_t; +typedef struct ol_pktlog_dev_t *ol_pktlog_dev_handle; +#endif /* #ifndef REMOVE_PKT_LOG */ +#endif /* _PKTLOG_ */ diff --git a/utils/pktlog/include/pktlog_ac.h b/utils/pktlog/include/pktlog_ac.h new file mode 100644 index 0000000000..4788db94b6 --- /dev/null +++ b/utils/pktlog/include/pktlog_ac.h @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _PKTLOG_AC_H_ +#define _PKTLOG_AC_H_ +#ifndef REMOVE_PKT_LOG + +#include "ol_if_athvar.h" +#include +#include +#include "osdep.h" +#include +#include +#include +#include "hif.h" + +#define NO_REG_FUNCS 4 + +/* Locking interface for pktlog */ +#define PKTLOG_LOCK_INIT(_pl_info) spin_lock_init(&(_pl_info)->log_lock) +#define PKTLOG_LOCK_DESTROY(_pl_info) +#define PKTLOG_LOCK(_pl_info) spin_lock(&(_pl_info)->log_lock) +#define PKTLOG_UNLOCK(_pl_info) spin_unlock(&(_pl_info)->log_lock) + +#define PKTLOG_MODE_SYSTEM 1 +#define PKTLOG_MODE_ADAPTER 2 + +/* + * The proc entry starts with magic number and version field which will be + * used by post processing scripts. These fields are not needed by applications + * that do not use these scripts. This is skipped using the offset value. + */ +#define PKTLOG_READ_OFFSET 8 + +/* Opaque softc */ +struct ol_ath_generic_softc_t; +typedef struct ol_ath_generic_softc_t *ol_ath_generic_softc_handle; +extern void pktlog_disable_adapter_logging(struct hif_opaque_softc *scn); +extern int pktlog_alloc_buf(struct hif_opaque_softc *scn); +extern void pktlog_release_buf(ol_txrx_pdev_handle pdev_txrx_handle); + +ssize_t pktlog_read_proc_entry(char *buf, size_t nbytes, loff_t *ppos, + struct ath_pktlog_info *pl_info, bool *read_complete); +int pktlog_send_per_pkt_stats_to_user(void); +A_STATUS +wdi_pktlog_unsubscribe(struct ol_txrx_pdev_t *txrx_pdev, uint32_t log_state); + +struct ol_pl_arch_dep_funcs { + void (*pktlog_init)(struct hif_opaque_softc *scn); + int (*pktlog_enable)(struct hif_opaque_softc *scn, int32_t log_state, + bool ini, uint8_t user, + uint32_t is_iwpriv_command); + int (*pktlog_setsize)(struct hif_opaque_softc *scn, int32_t log_state); + int (*pktlog_disable)(struct hif_opaque_softc *scn); +}; + +struct ol_pl_os_dep_funcs { + int (*pktlog_attach)(struct hif_opaque_softc *scn); + void (*pktlog_detach)(struct ol_txrx_pdev_t *handle); + +}; + +struct ath_pktlog_wmi_params { + WMI_PKTLOG_EVENT pktlog_event; + WMI_CMD_ID cmd_id; + bool ini_triggered; + uint8_t user_triggered; +}; + +extern struct ol_pl_arch_dep_funcs ol_pl_funcs; +extern struct ol_pl_os_dep_funcs *g_ol_pl_os_dep_funcs; + +/* Pktlog handler to save the state of the pktlogs */ +struct ol_pktlog_dev_t { + struct ol_pl_arch_dep_funcs *pl_funcs; + struct ath_pktlog_info *pl_info; + ol_ath_generic_softc_handle scn; + char *name; + bool tgt_pktlog_alloced; + bool is_pktlog_cb_subscribed; + bool mt_pktlog_enabled; + uint32_t htc_err_cnt; + uint8_t htc_endpoint; + void *htc_pdev; + bool vendor_cmd_send; +}; + +#define PKTLOG_SYSCTL_SIZE 14 +#define PKTLOG_MAX_SEND_QUEUE_DEPTH 64 + +/* + * Linux specific pktlog state information + */ +struct ath_pktlog_info_lnx { + struct ath_pktlog_info info; + struct ctl_table sysctls[PKTLOG_SYSCTL_SIZE]; + struct proc_dir_entry *proc_entry; + struct ctl_table_header *sysctl_header; +}; + +#define PL_INFO_LNX(_pl_info) ((struct ath_pktlog_info_lnx *)(_pl_info)) + +extern struct ol_pktlog_dev_t ol_pl_dev; + +/* + * WDI related data and functions + * Callback function to the WDI events + */ +void pktlog_callback(void *pdev, enum WDI_EVENT event, void *log_data); + +void pktlog_init(struct hif_opaque_softc *scn); +int pktlog_enable(struct hif_opaque_softc *scn, int32_t log_state, + bool, uint8_t, uint32_t); +int pktlog_setsize(struct hif_opaque_softc *scn, int32_t log_state); +int pktlog_disable(struct hif_opaque_softc *scn); +int pktlogmod_init(void *context); +void pktlogmod_exit(struct ol_txrx_pdev_t *handle); +int pktlog_htc_attach(void); +void pktlog_process_fw_msg(uint32_t *msg_word); + +#define ol_pktlog_attach(_scn) \ + do { \ + if (g_ol_pl_os_dep_funcs) { \ + g_ol_pl_os_dep_funcs->pktlog_attach(_scn); \ + } \ + } while (0) + +#define ol_pktlog_detach(_scn) \ + do { \ + if (g_ol_pl_os_dep_funcs) { \ + g_ol_pl_os_dep_funcs->pktlog_detach(_scn); \ + } \ + } while (0) + +#else /* REMOVE_PKT_LOG */ +#define ol_pktlog_attach(_scn) ({ (void)_scn; }) +#define ol_pktlog_detach(_scn) ({ (void)_scn; }) +static inline void pktlog_init(struct hif_opaque_softc *scn) +{ + return; +} +static int pktlog_enable(struct hif_opaque_softc *scn, int32_t log_state, + bool ini, uint8_t user, uint32_t is_iwpriv_command) +{ + return 0; +} +static int pktlog_setsize(struct hif_opaque_softc *scn, int32_t log_state) +{ + return 0; +} +static int pktlog_disable(struct hif_opaque_softc *scn) +{ + return 0; +} +static inline int pktlog_htc_attach(void) +{ + return 0; +} +static inline void pktlog_process_fw_msg(uint32_t *msg_word) +{ } +#endif /* REMOVE_PKT_LOG */ +#endif /* _PKTLOG_AC_H_ */ diff --git a/utils/pktlog/include/pktlog_ac_api.h b/utils/pktlog/include/pktlog_ac_api.h new file mode 100644 index 0000000000..d033ddb5ec --- /dev/null +++ b/utils/pktlog/include/pktlog_ac_api.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2012-2014, 2016-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * The file is used to define structures that are shared between + * kernel space and user space pktlog application. + */ + +#ifndef _PKTLOG_AC_API_ +#define _PKTLOG_AC_API_ +#ifndef REMOVE_PKT_LOG + +/** + * @typedef ol_pktlog_dev_handle + * @brief opaque handle for pktlog device object + */ +struct ol_pktlog_dev_t; +typedef struct ol_pktlog_dev_t *ol_pktlog_dev_handle; + +/** + * @typedef hif_opaque_softc_handle + * @brief opaque handle for hif_opaque_softc + */ +struct hif_opaque_softc; +typedef struct hif_opaque_softc *hif_opaque_softc_handle; + +/** + * @typedef net_device_handle + * @brief opaque handle linux phy device object + */ +struct net_device; +typedef struct net_device *net_device_handle; + +void ol_pl_sethandle(ol_pktlog_dev_handle *pl_handle, + hif_opaque_softc_handle scn); + +/* Packet log state information */ +#ifndef _PKTLOG_INFO +#define _PKTLOG_INFO +struct ath_pktlog_info { + struct ath_pktlog_buf *buf; + uint32_t log_state; + uint32_t saved_state; + uint32_t options; + + /* Size of buffer in bytes */ + int32_t buf_size; + spinlock_t log_lock; + + /* Threshold of TCP SACK packets for triggered stop */ + int sack_thr; + + /* # of tail packets to log after triggered stop */ + int tail_length; + + /* throuput threshold in bytes for triggered stop */ + uint32_t thruput_thresh; + + /* (aggregated or single) packet size in bytes */ + uint32_t pktlen; + + /* a temporary variable for counting TX throughput only */ + /* PER threshold for triggered stop, 10 for 10%, range [1, 99] */ + uint32_t per_thresh; + + /* Phyerr threshold for triggered stop */ + uint32_t phyerr_thresh; + + /* time period for counting trigger parameters, in milisecond */ + uint32_t trigger_interval; + uint32_t start_time_thruput; + uint32_t start_time_per; +}; +#endif /* _PKTLOG_INFO */ +#else /* REMOVE_PKT_LOG */ +typedef void *ol_pktlog_dev_handle; +#define ol_pl_sethandle(pl_handle, scn) \ + do { \ + (void)pl_handle; \ + (void)scn; \ + } while (0) + +#define ol_pl_set_name(dev) \ + do { \ + (void)scn; \ + (void)dev; \ + } while (0) + +#endif /* REMOVE_PKT_LOG */ +#endif /* _PKTLOG_AC_API_ */ diff --git a/utils/pktlog/include/pktlog_ac_i.h b/utils/pktlog/include/pktlog_ac_i.h new file mode 100644 index 0000000000..cd6417f5cf --- /dev/null +++ b/utils/pktlog/include/pktlog_ac_i.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _PKTLOG_AC_I_ +#define _PKTLOG_AC_I_ +#ifndef REMOVE_PKT_LOG + +#include +#include + +#ifdef FEATURE_PKTLOG +#define PKTLOG_DEFAULT_BUFSIZE (10 * 1024 * 1024) /* 10MB */ +#else +#define PKTLOG_DEFAULT_BUFSIZE (1 * 1024 * 1024) /* 1MB */ +#endif +#define PKTLOG_DEFAULT_SACK_THR 3 +#define PKTLOG_DEFAULT_TAIL_LENGTH 100 +#define PKTLOG_DEFAULT_THRUPUT_THRESH (64 * 1024) +#define PKTLOG_DEFAULT_PER_THRESH 30 +#define PKTLOG_DEFAULT_PHYERR_THRESH 300 +#define PKTLOG_DEFAULT_TRIGGER_INTERVAL 500 +struct ath_pktlog_arg { + struct ath_pktlog_info *pl_info; + uint32_t flags; + uint16_t missed_cnt; +#ifdef HELIUMPLUS + uint8_t log_type; + uint8_t macId; +#else + uint16_t log_type; +#endif + size_t log_size; + uint16_t timestamp; +#ifdef HELIUMPLUS + uint32_t type_specific_data; +#endif + char *buf; +}; + +void pktlog_getbuf_intsafe(struct ath_pktlog_arg *plarg); +char *pktlog_getbuf(struct ol_pktlog_dev_t *pl_dev, + struct ath_pktlog_info *pl_info, + size_t log_size, struct ath_pktlog_hdr *pl_hdr); + +A_STATUS process_tx_info(struct ol_txrx_pdev_t *pdev, void *data); +A_STATUS process_rx_info(void *pdev, void *data); +A_STATUS process_rx_info_remote(void *pdev, void *data); +A_STATUS process_rate_find(void *pdev, void *data); +A_STATUS process_rate_update(void *pdev, void *data); +A_STATUS process_sw_event(void *pdev, void *data); + + +#endif /* REMOVE_PKT_LOG */ +#endif diff --git a/utils/pktlog/linux_ac.c b/utils/pktlog/linux_ac.c new file mode 100644 index 0000000000..7e21475f86 --- /dev/null +++ b/utils/pktlog/linux_ac.c @@ -0,0 +1,931 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef REMOVE_PKT_LOG +#ifndef EXPORT_SYMTAB +#define EXPORT_SYMTAB +#endif +#ifndef __KERNEL__ +#define __KERNEL__ +#endif +/* + * Linux specific implementation of Pktlogs for 802.11ac + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "i_host_diag_core_log.h" +#include "host_diag_core_log.h" +#include "ani_global.h" + +#define PKTLOG_TAG "ATH_PKTLOG" +#define PKTLOG_DEVNAME_SIZE 32 +#define MAX_WLANDEV 1 + +#ifdef MULTI_IF_NAME +#define PKTLOG_PROC_DIR "ath_pktlog" MULTI_IF_NAME +#else +#define PKTLOG_PROC_DIR "ath_pktlog" +#endif + +/* Permissions for creating proc entries */ +#define PKTLOG_PROC_PERM 0444 +#define PKTLOG_PROCSYS_DIR_PERM 0555 +#define PKTLOG_PROCSYS_PERM 0644 + +#ifndef __MOD_INC_USE_COUNT +#define PKTLOG_MOD_INC_USE_COUNT do { \ + if (!try_module_get(THIS_MODULE)) { \ + printk(KERN_WARNING "try_module_get failed\n"); \ + } } while (0) + +#define PKTLOG_MOD_DEC_USE_COUNT module_put(THIS_MODULE) +#else +#define PKTLOG_MOD_INC_USE_COUNT MOD_INC_USE_COUNT +#define PKTLOG_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT +#endif + +static struct ath_pktlog_info *g_pktlog_info; + +static struct proc_dir_entry *g_pktlog_pde; + +static int pktlog_attach(struct hif_opaque_softc *sc); +static void pktlog_detach(struct ol_txrx_pdev_t *handle); +static int pktlog_open(struct inode *i, struct file *f); +static int pktlog_release(struct inode *i, struct file *f); +static int pktlog_mmap(struct file *f, struct vm_area_struct *vma); +static ssize_t pktlog_read(struct file *file, char *buf, size_t nbytes, + loff_t *ppos); + +static struct file_operations pktlog_fops = { + open: pktlog_open, + release:pktlog_release, + mmap : pktlog_mmap, + read : pktlog_read, +}; + +/* + * Linux implementation of helper functions + */ +static struct ol_pktlog_dev_t *cds_get_pl_handle(void) +{ + ol_txrx_pdev_handle pdev_txrx_handle; + pdev_txrx_handle = cds_get_context(QDF_MODULE_ID_TXRX); + if (!pdev_txrx_handle) { + QDF_ASSERT(0); + return NULL; + } + return pdev_txrx_handle->pl_dev; +} + +static struct ol_pktlog_dev_t *ol_get_pl_handle( + ol_txrx_pdev_handle pdev_txrx_handle) +{ + if (!pdev_txrx_handle) + return NULL; + return pdev_txrx_handle->pl_dev; +} + +void pktlog_disable_adapter_logging(struct hif_opaque_softc *scn) +{ + struct ol_pktlog_dev_t *pl_dev = cds_get_pl_handle(); + if (pl_dev) + pl_dev->pl_info->log_state = 0; +} + +int pktlog_alloc_buf(struct hif_opaque_softc *scn) +{ + uint32_t page_cnt; + unsigned long vaddr; + struct page *vpg; + struct ath_pktlog_info *pl_info; + ol_txrx_pdev_handle pdev_txrx_handle; + pdev_txrx_handle = cds_get_context(QDF_MODULE_ID_TXRX); + + if (!pdev_txrx_handle || !pdev_txrx_handle->pl_dev) { + printk(PKTLOG_TAG + "%s: Unable to allocate buffer " + "scn or scn->pdev_txrx_handle->pl_dev is null\n", + __func__); + return -EINVAL; + } + + pl_info = pdev_txrx_handle->pl_dev->pl_info; + + page_cnt = (sizeof(*(pl_info->buf)) + pl_info->buf_size) / PAGE_SIZE; + + pl_info->buf = vmalloc((page_cnt + 2) * PAGE_SIZE); + if (pl_info->buf == NULL) { + printk(PKTLOG_TAG + "%s: Unable to allocate buffer " + "(%d pages)\n", __func__, page_cnt); + return -ENOMEM; + } + + pl_info->buf = (struct ath_pktlog_buf *) + (((unsigned long)(pl_info->buf) + PAGE_SIZE - 1) + & PAGE_MASK); + + for (vaddr = (unsigned long)(pl_info->buf); + vaddr < ((unsigned long)(pl_info->buf) + (page_cnt * PAGE_SIZE)); + vaddr += PAGE_SIZE) { + vpg = vmalloc_to_page((const void *)vaddr); + SetPageReserved(vpg); + } + + return 0; +} + +void pktlog_release_buf(ol_txrx_pdev_handle pdev_txrx_handle) +{ + unsigned long page_cnt; + unsigned long vaddr; + struct page *vpg; + struct ath_pktlog_info *pl_info; + + if (!pdev_txrx_handle || !pdev_txrx_handle->pl_dev) { + printk(PKTLOG_TAG + "%s: Unable to allocate buffer" + "scn or scn->pdev_txrx_handle->pl_dev is null\n", + __func__); + return; + } + + pl_info = pdev_txrx_handle->pl_dev->pl_info; + + page_cnt = ((sizeof(*(pl_info->buf)) + pl_info->buf_size) / + PAGE_SIZE) + 1; + + for (vaddr = (unsigned long)(pl_info->buf); + vaddr < (unsigned long)(pl_info->buf) + (page_cnt * PAGE_SIZE); + vaddr += PAGE_SIZE) { + vpg = vmalloc_to_page((const void *)vaddr); + ClearPageReserved(vpg); + } + + vfree(pl_info->buf); + pl_info->buf = NULL; +} + +static void pktlog_cleanup(struct ath_pktlog_info *pl_info) +{ + pl_info->log_state = 0; + PKTLOG_LOCK_DESTROY(pl_info); +} + +/* sysctl procfs handler to enable pktlog */ +static int +qdf_sysctl_decl(ath_sysctl_pktlog_enable, ctl, write, filp, buffer, lenp, ppos) +{ + int ret, enable; + ol_ath_generic_softc_handle scn; + struct ol_pktlog_dev_t *pl_dev; + + scn = (ol_ath_generic_softc_handle) ctl->extra1; + + if (!scn) { + printk("%s: Invalid scn context\n", __func__); + ASSERT(0); + return -EINVAL; + } + + pl_dev = cds_get_pl_handle(); + + if (!pl_dev) { + printk("%s: Invalid pktlog context\n", __func__); + ASSERT(0); + return -ENODEV; + } + + ctl->data = &enable; + ctl->maxlen = sizeof(enable); + + if (write) { + ret = QDF_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, + lenp, ppos); + if (ret == 0) + ret = pl_dev->pl_funcs->pktlog_enable( + (struct hif_opaque_softc *)scn, enable, + cds_is_packet_log_enabled(), 0, 1); + else + printk(PKTLOG_TAG "%s:proc_dointvec failed\n", + __func__); + } else { + ret = QDF_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, + lenp, ppos); + if (ret) + printk(PKTLOG_TAG "%s:proc_dointvec failed\n", + __func__); + } + + ctl->data = NULL; + ctl->maxlen = 0; + + return ret; +} + +static int get_pktlog_bufsize(struct ol_pktlog_dev_t *pl_dev) +{ + return pl_dev->pl_info->buf_size; +} + +/* sysctl procfs handler to set/get pktlog size */ +static int +qdf_sysctl_decl(ath_sysctl_pktlog_size, ctl, write, filp, buffer, lenp, ppos) +{ + int ret, size; + ol_ath_generic_softc_handle scn; + struct ol_pktlog_dev_t *pl_dev; + + scn = (ol_ath_generic_softc_handle) ctl->extra1; + + if (!scn) { + printk("%s: Invalid scn context\n", __func__); + ASSERT(0); + return -EINVAL; + } + + pl_dev = cds_get_pl_handle(); + + if (!pl_dev) { + printk("%s: Invalid pktlog handle\n", __func__); + ASSERT(0); + return -ENODEV; + } + + ctl->data = &size; + ctl->maxlen = sizeof(size); + + if (write) { + ret = QDF_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, + lenp, ppos); + if (ret == 0) + ret = pl_dev->pl_funcs->pktlog_setsize( + (struct hif_opaque_softc *)scn, size); + } else { + size = get_pktlog_bufsize(pl_dev); + ret = QDF_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, + lenp, ppos); + } + + ctl->data = NULL; + ctl->maxlen = 0; + + return ret; +} + +/* Register sysctl table */ +static int pktlog_sysctl_register(struct hif_opaque_softc *scn) +{ + struct ol_pktlog_dev_t *pl_dev = cds_get_pl_handle(); + struct ath_pktlog_info_lnx *pl_info_lnx; + char *proc_name; + + if (pl_dev) { + pl_info_lnx = PL_INFO_LNX(pl_dev->pl_info); + proc_name = pl_dev->name; + } else { + pl_info_lnx = PL_INFO_LNX(g_pktlog_info); + proc_name = PKTLOG_PROC_SYSTEM; + } + + /* + * Setup the sysctl table for creating the following sysctl entries: + * /proc/sys/PKTLOG_PROC_DIR//enable for enabling/disabling + * pktlog + * /proc/sys/PKTLOG_PROC_DIR//size for changing the buffer size + */ + memset(pl_info_lnx->sysctls, 0, sizeof(pl_info_lnx->sysctls)); + pl_info_lnx->sysctls[0].procname = PKTLOG_PROC_DIR; + pl_info_lnx->sysctls[0].mode = PKTLOG_PROCSYS_DIR_PERM; + pl_info_lnx->sysctls[0].child = &pl_info_lnx->sysctls[2]; + + /* [1] is NULL terminator */ + pl_info_lnx->sysctls[2].procname = proc_name; + pl_info_lnx->sysctls[2].mode = PKTLOG_PROCSYS_DIR_PERM; + pl_info_lnx->sysctls[2].child = &pl_info_lnx->sysctls[4]; + + /* [3] is NULL terminator */ + pl_info_lnx->sysctls[4].procname = "enable"; + pl_info_lnx->sysctls[4].mode = PKTLOG_PROCSYS_PERM; + pl_info_lnx->sysctls[4].proc_handler = ath_sysctl_pktlog_enable; + pl_info_lnx->sysctls[4].extra1 = scn; + + pl_info_lnx->sysctls[5].procname = "size"; + pl_info_lnx->sysctls[5].mode = PKTLOG_PROCSYS_PERM; + pl_info_lnx->sysctls[5].proc_handler = ath_sysctl_pktlog_size; + pl_info_lnx->sysctls[5].extra1 = scn; + + pl_info_lnx->sysctls[6].procname = "options"; + pl_info_lnx->sysctls[6].mode = PKTLOG_PROCSYS_PERM; + pl_info_lnx->sysctls[6].proc_handler = proc_dointvec; + pl_info_lnx->sysctls[6].data = &pl_info_lnx->info.options; + pl_info_lnx->sysctls[6].maxlen = sizeof(pl_info_lnx->info.options); + + pl_info_lnx->sysctls[7].procname = "sack_thr"; + pl_info_lnx->sysctls[7].mode = PKTLOG_PROCSYS_PERM; + pl_info_lnx->sysctls[7].proc_handler = proc_dointvec; + pl_info_lnx->sysctls[7].data = &pl_info_lnx->info.sack_thr; + pl_info_lnx->sysctls[7].maxlen = sizeof(pl_info_lnx->info.sack_thr); + + pl_info_lnx->sysctls[8].procname = "tail_length"; + pl_info_lnx->sysctls[8].mode = PKTLOG_PROCSYS_PERM; + pl_info_lnx->sysctls[8].proc_handler = proc_dointvec; + pl_info_lnx->sysctls[8].data = &pl_info_lnx->info.tail_length; + pl_info_lnx->sysctls[8].maxlen = sizeof(pl_info_lnx->info.tail_length); + + pl_info_lnx->sysctls[9].procname = "thruput_thresh"; + pl_info_lnx->sysctls[9].mode = PKTLOG_PROCSYS_PERM; + pl_info_lnx->sysctls[9].proc_handler = proc_dointvec; + pl_info_lnx->sysctls[9].data = &pl_info_lnx->info.thruput_thresh; + pl_info_lnx->sysctls[9].maxlen = + sizeof(pl_info_lnx->info.thruput_thresh); + + pl_info_lnx->sysctls[10].procname = "phyerr_thresh"; + pl_info_lnx->sysctls[10].mode = PKTLOG_PROCSYS_PERM; + pl_info_lnx->sysctls[10].proc_handler = proc_dointvec; + pl_info_lnx->sysctls[10].data = &pl_info_lnx->info.phyerr_thresh; + pl_info_lnx->sysctls[10].maxlen = + sizeof(pl_info_lnx->info.phyerr_thresh); + + pl_info_lnx->sysctls[11].procname = "per_thresh"; + pl_info_lnx->sysctls[11].mode = PKTLOG_PROCSYS_PERM; + pl_info_lnx->sysctls[11].proc_handler = proc_dointvec; + pl_info_lnx->sysctls[11].data = &pl_info_lnx->info.per_thresh; + pl_info_lnx->sysctls[11].maxlen = sizeof(pl_info_lnx->info.per_thresh); + + pl_info_lnx->sysctls[12].procname = "trigger_interval"; + pl_info_lnx->sysctls[12].mode = PKTLOG_PROCSYS_PERM; + pl_info_lnx->sysctls[12].proc_handler = proc_dointvec; + pl_info_lnx->sysctls[12].data = &pl_info_lnx->info.trigger_interval; + pl_info_lnx->sysctls[12].maxlen = + sizeof(pl_info_lnx->info.trigger_interval); + /* [13] is NULL terminator */ + + /* and register everything */ + /* register_sysctl_table changed from 2.6.21 onwards */ + pl_info_lnx->sysctl_header = + register_sysctl_table(pl_info_lnx->sysctls); + + if (!pl_info_lnx->sysctl_header) { + printk("%s: failed to register sysctls!\n", proc_name); + return -EINVAL; + } + + return 0; +} + +/* + * Initialize logging for system or adapter + * Parameter scn should be NULL for system wide logging + */ +static int pktlog_attach(struct hif_opaque_softc *scn) +{ + struct ol_pktlog_dev_t *pl_dev; + struct ath_pktlog_info_lnx *pl_info_lnx; + char *proc_name; + struct proc_dir_entry *proc_entry; + + pl_dev = cds_get_pl_handle(); + + if (pl_dev != NULL) { + pl_info_lnx = kmalloc(sizeof(*pl_info_lnx), GFP_KERNEL); + if (pl_info_lnx == NULL) { + printk(PKTLOG_TAG "%s:allocation failed for pl_info\n", + __func__); + return -ENOMEM; + } + pl_dev->pl_info = &pl_info_lnx->info; + pl_dev->name = WLANDEV_BASENAME; + proc_name = pl_dev->name; + if (!pl_dev->pl_funcs) + pl_dev->pl_funcs = &ol_pl_funcs; + + /* + * Valid for both direct attach and offload architecture + */ + pl_dev->pl_funcs->pktlog_init(scn); + } else { + return -EINVAL; + } + + /* + * initialize log info + * might be good to move to pktlog_init + */ + /* pl_dev->tgt_pktlog_alloced = false; */ + pl_dev->vendor_cmd_send = false; + pl_info_lnx->proc_entry = NULL; + pl_info_lnx->sysctl_header = NULL; + + proc_entry = proc_create_data(proc_name, PKTLOG_PROC_PERM, + g_pktlog_pde, &pktlog_fops, + &pl_info_lnx->info); + + if (proc_entry == NULL) { + printk(PKTLOG_TAG "%s: create_proc_entry failed for %s\n", + __func__, proc_name); + goto attach_fail1; + } + + pl_info_lnx->proc_entry = proc_entry; + + if (pktlog_sysctl_register(scn)) { + printk(PKTLOG_TAG "%s: sysctl register failed for %s\n", + __func__, proc_name); + goto attach_fail2; + } + return 0; + +attach_fail2: + remove_proc_entry(proc_name, g_pktlog_pde); + +attach_fail1: + if (pl_dev) + kfree(pl_dev->pl_info); + return -EINVAL; +} + +static void pktlog_sysctl_unregister(struct ol_pktlog_dev_t *pl_dev) +{ + struct ath_pktlog_info_lnx *pl_info_lnx; + + if (!pl_dev) { + printk("%s: Invalid pktlog context\n", __func__); + ASSERT(0); + return; + } + + pl_info_lnx = (pl_dev) ? PL_INFO_LNX(pl_dev->pl_info) : + PL_INFO_LNX(g_pktlog_info); + + if (pl_info_lnx->sysctl_header) { + unregister_sysctl_table(pl_info_lnx->sysctl_header); + pl_info_lnx->sysctl_header = NULL; + } +} + +static void pktlog_detach(struct ol_txrx_pdev_t *handle) +{ + struct ol_txrx_pdev_t *txrx_pdev; + struct ol_pktlog_dev_t *pl_dev; + struct ath_pktlog_info *pl_info; + + txrx_pdev = handle; + if (!txrx_pdev) { + printk("%s: Invalid txrx_pdev context\n", __func__); + ASSERT(0); + return; + } + + pl_dev = txrx_pdev->pl_dev; + if (!pl_dev) { + printk("%s: Invalid pktlog context\n", __func__); + ASSERT(0); + return; + } + + pl_info = pl_dev->pl_info; + remove_proc_entry(WLANDEV_BASENAME, g_pktlog_pde); + pktlog_sysctl_unregister(pl_dev); + pktlog_cleanup(pl_info); + + if (pl_info->buf) { + pktlog_release_buf(txrx_pdev); + pl_dev->tgt_pktlog_alloced = false; + } + + if (pl_dev) { + kfree(pl_info); + pl_dev->pl_info = NULL; + } +} + +static int pktlog_open(struct inode *i, struct file *f) +{ + PKTLOG_MOD_INC_USE_COUNT; + return 0; +} + +static int pktlog_release(struct inode *i, struct file *f) +{ + PKTLOG_MOD_DEC_USE_COUNT; + return 0; +} + +#ifndef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +/** + * pktlog_read_proc_entry() - This function is used to read data from the + * proc entry into the readers buffer + * @buf: Readers buffer + * @nbytes: Number of bytes to read + * @ppos: Offset within the drivers buffer + * @pl_info: Packet log information pointer + * @read_complete: Boolean value indication whether read is complete + * + * This function is used to read data from the proc entry into the readers + * buffer. Its functionality is similar to 'pktlog_read' which does + * copy to user to the user space buffer + * + * Return: Number of bytes read from the buffer + * + */ + ssize_t +pktlog_read_proc_entry(char *buf, size_t nbytes, loff_t *ppos, + struct ath_pktlog_info *pl_info, bool *read_complete) +{ + size_t bufhdr_size; + size_t count = 0, ret_val = 0; + int rem_len; + int start_offset, end_offset; + int fold_offset, ppos_data, cur_rd_offset, cur_wr_offset; + struct ath_pktlog_buf *log_buf = pl_info->buf; + *read_complete = false; + + if (log_buf == NULL) { + *read_complete = true; + return 0; + } + + if (*ppos == 0 && pl_info->log_state) { + pl_info->saved_state = pl_info->log_state; + pl_info->log_state = 0; + } + + bufhdr_size = sizeof(log_buf->bufhdr); + + /* copy valid log entries from circular buffer into user space */ + rem_len = nbytes; + count = 0; + + if (*ppos < bufhdr_size) { + count = MIN((bufhdr_size - *ppos), rem_len); + qdf_mem_copy(buf, ((char *)&log_buf->bufhdr) + *ppos, + count); + rem_len -= count; + ret_val += count; + } + + start_offset = log_buf->rd_offset; + cur_wr_offset = log_buf->wr_offset; + + if ((rem_len == 0) || (start_offset < 0)) + goto rd_done; + + fold_offset = -1; + cur_rd_offset = start_offset; + + /* Find the last offset and fold-offset if the buffer is folded */ + do { + struct ath_pktlog_hdr *log_hdr; + int log_data_offset; + + log_hdr = (struct ath_pktlog_hdr *) (log_buf->log_data + + cur_rd_offset); + + log_data_offset = cur_rd_offset + sizeof(struct ath_pktlog_hdr); + + if ((fold_offset == -1) + && ((pl_info->buf_size - log_data_offset) + <= log_hdr->size)) + fold_offset = log_data_offset - 1; + + PKTLOG_MOV_RD_IDX(cur_rd_offset, log_buf, pl_info->buf_size); + + if ((fold_offset == -1) && (cur_rd_offset == 0) + && (cur_rd_offset != cur_wr_offset)) + fold_offset = log_data_offset + log_hdr->size - 1; + + end_offset = log_data_offset + log_hdr->size - 1; + } while (cur_rd_offset != cur_wr_offset); + + ppos_data = *ppos + ret_val - bufhdr_size + start_offset; + + if (fold_offset == -1) { + if (ppos_data > end_offset) + goto rd_done; + + count = MIN(rem_len, (end_offset - ppos_data + 1)); + qdf_mem_copy(buf + ret_val, + log_buf->log_data + ppos_data, + count); + ret_val += count; + rem_len -= count; + } else { + if (ppos_data <= fold_offset) { + count = MIN(rem_len, (fold_offset - ppos_data + 1)); + qdf_mem_copy(buf + ret_val, + log_buf->log_data + ppos_data, + count); + ret_val += count; + rem_len -= count; + } + + if (rem_len == 0) + goto rd_done; + + ppos_data = + *ppos + ret_val - (bufhdr_size + + (fold_offset - start_offset + 1)); + + if (ppos_data <= end_offset) { + count = MIN(rem_len, (end_offset - ppos_data + 1)); + qdf_mem_copy(buf + ret_val, + log_buf->log_data + ppos_data, + count); + ret_val += count; + rem_len -= count; + } + } + +rd_done: + if ((ret_val < nbytes) && pl_info->saved_state) { + pl_info->log_state = pl_info->saved_state; + pl_info->saved_state = 0; + } + *ppos += ret_val; + + if (ret_val == 0) { + PKTLOG_LOCK(pl_info); + /* Write pointer might have been updated during the read. + * So, if some data is written into, lets not reset the pointers + * We can continue to read from the offset position + */ + if (cur_wr_offset != log_buf->wr_offset) { + *read_complete = false; + } else { + pl_info->buf->rd_offset = -1; + pl_info->buf->wr_offset = 0; + pl_info->buf->bytes_written = 0; + pl_info->buf->offset = PKTLOG_READ_OFFSET; + *read_complete = true; + } + PKTLOG_UNLOCK(pl_info); + } + + return ret_val; +} + +static ssize_t +pktlog_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos) +{ + size_t bufhdr_size; + size_t count = 0, ret_val = 0; + int rem_len; + int start_offset, end_offset; + int fold_offset, ppos_data, cur_rd_offset; + struct ath_pktlog_info *pl_info; + struct ath_pktlog_buf *log_buf; + + pl_info = (struct ath_pktlog_info *) + PDE_DATA(file->f_path.dentry->d_inode); + if (!pl_info) + return 0; + + log_buf = pl_info->buf; + + if (log_buf == NULL) + return 0; + + if (pl_info->log_state) { + /* Read is not allowed when write is going on + * When issuing cat command, ensure to send + * pktlog disable command first. + */ + return -EINVAL; + } + + if (*ppos == 0 && pl_info->log_state) { + pl_info->saved_state = pl_info->log_state; + pl_info->log_state = 0; + } + + bufhdr_size = sizeof(log_buf->bufhdr); + + /* copy valid log entries from circular buffer into user space */ + rem_len = nbytes; + count = 0; + + if (*ppos < bufhdr_size) { + count = QDF_MIN((bufhdr_size - *ppos), rem_len); + if (copy_to_user(buf, ((char *)&log_buf->bufhdr) + *ppos, + count)) + return -EFAULT; + rem_len -= count; + ret_val += count; + } + + start_offset = log_buf->rd_offset; + + if ((rem_len == 0) || (start_offset < 0)) + goto rd_done; + + fold_offset = -1; + cur_rd_offset = start_offset; + + /* Find the last offset and fold-offset if the buffer is folded */ + do { + struct ath_pktlog_hdr *log_hdr; + int log_data_offset; + + log_hdr = (struct ath_pktlog_hdr *)(log_buf->log_data + + cur_rd_offset); + + log_data_offset = cur_rd_offset + sizeof(struct ath_pktlog_hdr); + + if ((fold_offset == -1) + && ((pl_info->buf_size - log_data_offset) + <= log_hdr->size)) + fold_offset = log_data_offset - 1; + + PKTLOG_MOV_RD_IDX(cur_rd_offset, log_buf, pl_info->buf_size); + + if ((fold_offset == -1) && (cur_rd_offset == 0) + && (cur_rd_offset != log_buf->wr_offset)) + fold_offset = log_data_offset + log_hdr->size - 1; + + end_offset = log_data_offset + log_hdr->size - 1; + } while (cur_rd_offset != log_buf->wr_offset); + + ppos_data = *ppos + ret_val - bufhdr_size + start_offset; + + if (fold_offset == -1) { + if (ppos_data > end_offset) + goto rd_done; + + count = QDF_MIN(rem_len, (end_offset - ppos_data + 1)); + if (copy_to_user(buf + ret_val, + log_buf->log_data + ppos_data, count)) + return -EFAULT; + ret_val += count; + rem_len -= count; + } else { + if (ppos_data <= fold_offset) { + count = QDF_MIN(rem_len, (fold_offset - ppos_data + 1)); + if (copy_to_user(buf + ret_val, + log_buf->log_data + ppos_data, count)) + return -EFAULT; + ret_val += count; + rem_len -= count; + } + + if (rem_len == 0) + goto rd_done; + + ppos_data = + *ppos + ret_val - (bufhdr_size + + (fold_offset - start_offset + 1)); + + if (ppos_data <= end_offset) { + count = QDF_MIN(rem_len, (end_offset - ppos_data + 1)); + if (copy_to_user(buf + ret_val, + log_buf->log_data + ppos_data, count)) + return -EFAULT; + ret_val += count; + rem_len -= count; + } + } + +rd_done: + if ((ret_val < nbytes) && pl_info->saved_state) { + pl_info->log_state = pl_info->saved_state; + pl_info->saved_state = 0; + } + *ppos += ret_val; + + return ret_val; +} + +#ifndef VMALLOC_VMADDR +#define VMALLOC_VMADDR(x) ((unsigned long)(x)) +#endif + +/* vma operations for mapping vmalloced area to user space */ +static void pktlog_vopen(struct vm_area_struct *vma) +{ + PKTLOG_MOD_INC_USE_COUNT; +} + +static void pktlog_vclose(struct vm_area_struct *vma) +{ + PKTLOG_MOD_DEC_USE_COUNT; +} + +static int pktlog_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + unsigned long address = (unsigned long)vmf->virtual_address; + + if (address == 0UL) + return VM_FAULT_NOPAGE; + + if (vmf->pgoff > vma->vm_end) + return VM_FAULT_SIGBUS; + + get_page(virt_to_page((void *)address)); + vmf->page = virt_to_page((void *)address); + return 0; +} + +static struct vm_operations_struct pktlog_vmops = { + open: pktlog_vopen, + close:pktlog_vclose, + fault:pktlog_fault, +}; + +static int pktlog_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct ath_pktlog_info *pl_info; + + pl_info = (struct ath_pktlog_info *) + PDE_DATA(file->f_path.dentry->d_inode); + + if (vma->vm_pgoff != 0) { + /* Entire buffer should be mapped */ + return -EINVAL; + } + + if (!pl_info->buf) { + printk(PKTLOG_TAG "%s: Log buffer unavailable\n", __func__); + return -ENOMEM; + } + + vma->vm_flags |= VM_LOCKED; + vma->vm_ops = &pktlog_vmops; + pktlog_vopen(vma); + return 0; +} + +int pktlogmod_init(void *context) +{ + int ret; + + /* create the proc directory entry */ + g_pktlog_pde = proc_mkdir(PKTLOG_PROC_DIR, NULL); + + if (g_pktlog_pde == NULL) { + printk(PKTLOG_TAG "%s: proc_mkdir failed\n", __func__); + return -EPERM; + } + + /* Attach packet log */ + ret = pktlog_attach((struct hif_opaque_softc *)context); + + if (ret) + goto attach_fail; + + return ret; + +attach_fail: + remove_proc_entry(PKTLOG_PROC_DIR, NULL); + g_pktlog_pde = NULL; + return ret; +} + +void pktlogmod_exit(struct ol_txrx_pdev_t *handle) +{ + struct ol_pktlog_dev_t *pl_dev; + + pl_dev = ol_get_pl_handle(handle); + + if (!pl_dev || g_pktlog_pde == NULL) + return; + + pktlog_detach(handle); + /* + * pdev kill needs to be implemented + */ + remove_proc_entry(PKTLOG_PROC_DIR, NULL); +} +#endif diff --git a/utils/pktlog/pktlog_ac.c b/utils/pktlog/pktlog_ac.c new file mode 100644 index 0000000000..642d44f191 --- /dev/null +++ b/utils/pktlog/pktlog_ac.c @@ -0,0 +1,715 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef REMOVE_PKT_LOG +#include "qdf_mem.h" +#include "athdefs.h" +#include "pktlog_ac_i.h" +#include "cds_api.h" +#include "wma_types.h" +#include "htc.h" + +wdi_event_subscribe PKTLOG_TX_SUBSCRIBER; +wdi_event_subscribe PKTLOG_RX_SUBSCRIBER; +wdi_event_subscribe PKTLOG_RX_REMOTE_SUBSCRIBER; +wdi_event_subscribe PKTLOG_RCFIND_SUBSCRIBER; +wdi_event_subscribe PKTLOG_RCUPDATE_SUBSCRIBER; +wdi_event_subscribe PKTLOG_SW_EVENT_SUBSCRIBER; + +struct ol_pl_arch_dep_funcs ol_pl_funcs = { + .pktlog_init = pktlog_init, + .pktlog_enable = pktlog_enable, + .pktlog_setsize = pktlog_setsize, + .pktlog_disable = pktlog_disable, /* valid for f/w disable */ +}; + +struct ol_pktlog_dev_t ol_pl_dev = { + .pl_funcs = &ol_pl_funcs, +}; + +void ol_pl_sethandle(ol_pktlog_dev_handle *pl_handle, + struct hif_opaque_softc *scn) +{ + ol_pl_dev.scn = (ol_ath_generic_softc_handle) scn; + *pl_handle = &ol_pl_dev; +} + +static A_STATUS pktlog_wma_post_msg(WMI_PKTLOG_EVENT event_types, + WMI_CMD_ID cmd_id, bool ini_triggered, + uint8_t user_triggered) +{ + struct scheduler_msg msg = { 0 }; + QDF_STATUS status; + struct ath_pktlog_wmi_params *param; + + param = qdf_mem_malloc(sizeof(struct ath_pktlog_wmi_params)); + + if (!param) + return A_NO_MEMORY; + + param->cmd_id = cmd_id; + param->pktlog_event = event_types; + param->ini_triggered = ini_triggered; + param->user_triggered = user_triggered; + + msg.type = WMA_PKTLOG_ENABLE_REQ; + msg.bodyptr = param; + msg.bodyval = 0; + + status = scheduler_post_msg(QDF_MODULE_ID_WMA, &msg); + + if (status != QDF_STATUS_SUCCESS) { + qdf_mem_free(param); + return A_ERROR; + } + + return A_OK; +} + +static inline A_STATUS +pktlog_enable_tgt(struct hif_opaque_softc *_scn, uint32_t log_state, + bool ini_triggered, uint8_t user_triggered) +{ + uint32_t types = 0; + + if (log_state & ATH_PKTLOG_TX) + types |= WMI_PKTLOG_EVENT_TX; + + if (log_state & ATH_PKTLOG_RX) + types |= WMI_PKTLOG_EVENT_RX; + + if (log_state & ATH_PKTLOG_RCFIND) + types |= WMI_PKTLOG_EVENT_RCF; + + if (log_state & ATH_PKTLOG_RCUPDATE) + types |= WMI_PKTLOG_EVENT_RCU; + + if (log_state & ATH_PKTLOG_SW_EVENT) + types |= WMI_PKTLOG_EVENT_SW; + + return pktlog_wma_post_msg(types, WMI_PDEV_PKTLOG_ENABLE_CMDID, + ini_triggered, user_triggered); +} + +static inline A_STATUS +wdi_pktlog_subscribe(struct ol_txrx_pdev_t *txrx_pdev, int32_t log_state) +{ + if (!txrx_pdev) { + printk("Invalid pdev in %s\n", __func__); + return A_ERROR; + } + if (log_state & ATH_PKTLOG_TX) { + if (wdi_event_sub(txrx_pdev, + &PKTLOG_TX_SUBSCRIBER, WDI_EVENT_TX_STATUS)) { + return A_ERROR; + } + } + if (log_state & ATH_PKTLOG_RX) { + if (wdi_event_sub(txrx_pdev, + &PKTLOG_RX_SUBSCRIBER, WDI_EVENT_RX_DESC)) { + return A_ERROR; + } + if (wdi_event_sub(txrx_pdev, + &PKTLOG_RX_REMOTE_SUBSCRIBER, + WDI_EVENT_RX_DESC_REMOTE)) { + return A_ERROR; + } + } + if (log_state & ATH_PKTLOG_RCFIND) { + if (wdi_event_sub(txrx_pdev, + &PKTLOG_RCFIND_SUBSCRIBER, + WDI_EVENT_RATE_FIND)) { + return A_ERROR; + } + } + if (log_state & ATH_PKTLOG_RCUPDATE) { + if (wdi_event_sub(txrx_pdev, + &PKTLOG_RCUPDATE_SUBSCRIBER, + WDI_EVENT_RATE_UPDATE)) { + return A_ERROR; + } + } + if (log_state & ATH_PKTLOG_SW_EVENT) { + if (wdi_event_sub(txrx_pdev, + &PKTLOG_SW_EVENT_SUBSCRIBER, + WDI_EVENT_SW_EVENT)) { + return A_ERROR; + } + } + + return A_OK; +} + +void pktlog_callback(void *pdev, enum WDI_EVENT event, void *log_data) +{ + switch (event) { + case WDI_EVENT_TX_STATUS: + { + /* + * process TX message + */ + if (process_tx_info(pdev, log_data)) { + printk("Unable to process TX info\n"); + return; + } + break; + } + case WDI_EVENT_RX_DESC: + { + /* + * process RX message for local frames + */ + if (process_rx_info(pdev, log_data)) { + printk("Unable to process RX info\n"); + return; + } + break; + } + case WDI_EVENT_RX_DESC_REMOTE: + { + /* + * process RX message for remote frames + */ + if (process_rx_info_remote(pdev, log_data)) { + printk("Unable to process RX info\n"); + return; + } + break; + } + case WDI_EVENT_RATE_FIND: + { + /* + * process RATE_FIND message + */ + if (process_rate_find(pdev, log_data)) { + printk("Unable to process RC_FIND info\n"); + return; + } + break; + } + case WDI_EVENT_RATE_UPDATE: + { + /* + * process RATE_UPDATE message + */ + if (process_rate_update(pdev, log_data)) { + printk("Unable to process RC_UPDATE\n"); + return; + } + break; + } + case WDI_EVENT_SW_EVENT: + { + /* + * process SW EVENT message + */ + if (process_sw_event(pdev, log_data)) { + printk("Unable to process SW_EVENT\n"); + return; + } + break; + } + default: + break; + } +} + +A_STATUS +wdi_pktlog_unsubscribe(struct ol_txrx_pdev_t *txrx_pdev, uint32_t log_state) +{ + if (log_state & ATH_PKTLOG_TX) { + if (wdi_event_unsub(txrx_pdev, + &PKTLOG_TX_SUBSCRIBER, + WDI_EVENT_TX_STATUS)) { + return A_ERROR; + } + } + if (log_state & ATH_PKTLOG_RX) { + if (wdi_event_unsub(txrx_pdev, + &PKTLOG_RX_SUBSCRIBER, WDI_EVENT_RX_DESC)) { + return A_ERROR; + } + if (wdi_event_unsub(txrx_pdev, + &PKTLOG_RX_REMOTE_SUBSCRIBER, + WDI_EVENT_RX_DESC_REMOTE)) { + return A_ERROR; + } + } + if (log_state & ATH_PKTLOG_RCFIND) { + if (wdi_event_unsub(txrx_pdev, + &PKTLOG_RCFIND_SUBSCRIBER, + WDI_EVENT_RATE_FIND)) { + return A_ERROR; + } + } + if (log_state & ATH_PKTLOG_RCUPDATE) { + if (wdi_event_unsub(txrx_pdev, + &PKTLOG_RCUPDATE_SUBSCRIBER, + WDI_EVENT_RATE_UPDATE)) { + return A_ERROR; + } + } + if (log_state & ATH_PKTLOG_RCUPDATE) { + if (wdi_event_unsub(txrx_pdev, + &PKTLOG_SW_EVENT_SUBSCRIBER, + WDI_EVENT_SW_EVENT)) { + return A_ERROR; + } + } + return A_OK; +} + +int pktlog_disable(struct hif_opaque_softc *scn) +{ + struct ol_txrx_pdev_t *txrx_pdev = + cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_pktlog_dev_t *pl_dev; + struct ath_pktlog_info *pl_info; + + if (txrx_pdev == NULL || + txrx_pdev->pl_dev == NULL || + txrx_pdev->pl_dev->pl_info == NULL) + return -EFAULT; + + pl_dev = txrx_pdev->pl_dev; + pl_info = pl_dev->pl_info; + + if (pktlog_wma_post_msg(0, WMI_PDEV_PKTLOG_DISABLE_CMDID, 0, 0)) { + printk("Failed to disable pktlog in target\n"); + return -EINVAL; + } + + if (pl_dev->is_pktlog_cb_subscribed && + wdi_pktlog_unsubscribe(txrx_pdev, pl_info->log_state)) { + printk("Cannot unsubscribe pktlog from the WDI\n"); + return -EINVAL; + } + pl_dev->is_pktlog_cb_subscribed = false; + return 0; +} + +void pktlog_init(struct hif_opaque_softc *scn) +{ + struct ath_pktlog_info *pl_info; + ol_txrx_pdev_handle pdev_txrx_handle; + pdev_txrx_handle = cds_get_context(QDF_MODULE_ID_TXRX); + + if (pdev_txrx_handle == NULL || + pdev_txrx_handle->pl_dev == NULL || + pdev_txrx_handle->pl_dev->pl_info == NULL) + return; + + pl_info = pdev_txrx_handle->pl_dev->pl_info; + + OS_MEMZERO(pl_info, sizeof(*pl_info)); + PKTLOG_LOCK_INIT(pl_info); + + pl_info->buf_size = PKTLOG_DEFAULT_BUFSIZE; + pl_info->buf = NULL; + pl_info->log_state = 0; + pl_info->sack_thr = PKTLOG_DEFAULT_SACK_THR; + pl_info->tail_length = PKTLOG_DEFAULT_TAIL_LENGTH; + pl_info->thruput_thresh = PKTLOG_DEFAULT_THRUPUT_THRESH; + pl_info->per_thresh = PKTLOG_DEFAULT_PER_THRESH; + pl_info->phyerr_thresh = PKTLOG_DEFAULT_PHYERR_THRESH; + pl_info->trigger_interval = PKTLOG_DEFAULT_TRIGGER_INTERVAL; + pl_info->pktlen = 0; + pl_info->start_time_thruput = 0; + pl_info->start_time_per = 0; + pdev_txrx_handle->pl_dev->vendor_cmd_send = false; + + PKTLOG_TX_SUBSCRIBER.callback = pktlog_callback; + PKTLOG_RX_SUBSCRIBER.callback = pktlog_callback; + PKTLOG_RX_REMOTE_SUBSCRIBER.callback = pktlog_callback; + PKTLOG_RCFIND_SUBSCRIBER.callback = pktlog_callback; + PKTLOG_RCUPDATE_SUBSCRIBER.callback = pktlog_callback; + PKTLOG_SW_EVENT_SUBSCRIBER.callback = pktlog_callback; +} + +int pktlog_enable(struct hif_opaque_softc *scn, int32_t log_state, + bool ini_triggered, uint8_t user_triggered, + uint32_t is_iwpriv_command) +{ + struct ol_pktlog_dev_t *pl_dev; + struct ath_pktlog_info *pl_info; + struct ol_txrx_pdev_t *txrx_pdev; + int error; + + if (!scn) { + printk("%s: Invalid scn context\n", __func__); + ASSERT(0); + return -EINVAL; + } + + txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX); + if (!txrx_pdev) { + printk("%s: Invalid txrx_pdev context\n", __func__); + ASSERT(0); + return -EINVAL; + } + + pl_dev = txrx_pdev->pl_dev; + if (!pl_dev) { + printk("%s: Invalid pktlog context\n", __func__); + ASSERT(0); + return -EINVAL; + } + + pl_info = pl_dev->pl_info; + + if (!pl_info) + return 0; + + /* is_iwpriv_command : 0 indicates its a vendor command + * log_state: 0 indicates pktlog disable command + * vendor_cmd_send flag; false means no vendor pktlog enable + * command was sent previously + */ + if (is_iwpriv_command == 0 && log_state == 0 && + pl_dev->vendor_cmd_send == false) + return 0; + + if (!pl_dev->tgt_pktlog_alloced) { + if (pl_info->buf == NULL) { + error = pktlog_alloc_buf(scn); + + if (error != 0) + return error; + + if (!pl_info->buf) { + printk("%s: pktlog buf alloc failed\n", + __func__); + ASSERT(0); + return -ENOMEM; + } + + } + + pl_info->buf->bufhdr.version = CUR_PKTLOG_VER; + pl_info->buf->bufhdr.magic_num = PKTLOG_MAGIC_NUM; + pl_info->buf->wr_offset = 0; + pl_info->buf->rd_offset = -1; + /* These below variables are used by per packet stats*/ + pl_info->buf->bytes_written = 0; + pl_info->buf->msg_index = 1; + pl_info->buf->offset = PKTLOG_READ_OFFSET; + + pl_info->start_time_thruput = os_get_timestamp(); + pl_info->start_time_per = pl_info->start_time_thruput; + + pl_dev->tgt_pktlog_alloced = true; + } + + if (log_state != 0) { + /* WDI subscribe */ + if ((!pl_dev->is_pktlog_cb_subscribed) && + wdi_pktlog_subscribe(txrx_pdev, log_state)) { + printk("Unable to subscribe to the WDI %s\n", __func__); + return -EINVAL; + } + pl_dev->is_pktlog_cb_subscribed = true; + /* WMI command to enable pktlog on the firmware */ + if (pktlog_enable_tgt(scn, log_state, ini_triggered, + user_triggered)) { + printk("Device cannot be enabled, %s\n", __func__); + return -EINVAL; + } + + if (is_iwpriv_command == 0) + pl_dev->vendor_cmd_send = true; + } else { + pl_dev->pl_funcs->pktlog_disable(scn); + if (is_iwpriv_command == 0) + pl_dev->vendor_cmd_send = false; + } + + pl_info->log_state = log_state; + return 0; +} + +int pktlog_setsize(struct hif_opaque_softc *scn, int32_t size) +{ + ol_txrx_pdev_handle pdev_txrx_handle = + cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_pktlog_dev_t *pl_dev; + struct ath_pktlog_info *pl_info; + + if (pdev_txrx_handle == NULL || + pdev_txrx_handle->pl_dev == NULL || + pdev_txrx_handle->pl_dev->pl_info == NULL) + return -EFAULT; + + pl_dev = pdev_txrx_handle->pl_dev; + pl_info = pl_dev->pl_info; + + if (size < 0) + return -EINVAL; + + if (size == pl_info->buf_size) { + qdf_print("%s: Pktlog Buff Size is already of same size.", + __func__); + return 0; + } + + if (pl_info->log_state) { + qdf_print("%s: Logging should be disabled before changing" + "buffer size.", __func__); + return -EINVAL; + } + + if (pl_info->buf != NULL) { + if (pl_dev->is_pktlog_cb_subscribed && + wdi_pktlog_unsubscribe(pdev_txrx_handle, + pl_info->log_state)) { + printk("Cannot unsubscribe pktlog from the WDI\n"); + return -EFAULT; + } + pktlog_release_buf(pdev_txrx_handle); + pl_dev->is_pktlog_cb_subscribed = false; + pl_dev->tgt_pktlog_alloced = false; + } + + if (size != 0) { + qdf_print("%s: New Pktlog Buff Size is %d\n", __func__, size); + pl_info->buf_size = size; + } + + return 0; +} + +/** + * pktlog_process_fw_msg() - process packetlog message + * @buff: buffer + * + * Return: None + */ +void pktlog_process_fw_msg(uint32_t *buff) +{ + uint32_t *pl_hdr; + uint32_t log_type; + struct ol_txrx_pdev_t *txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX); + + if (!txrx_pdev) { + qdf_print("%s: txrx_pdev is NULL", __func__); + return; + } + + pl_hdr = buff; + log_type = + (*(pl_hdr + 1) & ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; + if ((log_type == PKTLOG_TYPE_TX_CTRL) + || (log_type == PKTLOG_TYPE_TX_STAT) + || (log_type == PKTLOG_TYPE_TX_MSDU_ID) + || (log_type == PKTLOG_TYPE_TX_FRM_HDR) + || (log_type == PKTLOG_TYPE_TX_VIRT_ADDR)) + wdi_event_handler(WDI_EVENT_TX_STATUS, + txrx_pdev, pl_hdr); + else if (log_type == PKTLOG_TYPE_RC_FIND) + wdi_event_handler(WDI_EVENT_RATE_FIND, + txrx_pdev, pl_hdr); + else if (log_type == PKTLOG_TYPE_RC_UPDATE) + wdi_event_handler(WDI_EVENT_RATE_UPDATE, + txrx_pdev, pl_hdr); + else if (log_type == PKTLOG_TYPE_RX_STAT) + wdi_event_handler(WDI_EVENT_RX_DESC, + txrx_pdev, pl_hdr); + else if (log_type == PKTLOG_TYPE_SW_EVENT) + wdi_event_handler(WDI_EVENT_SW_EVENT, + txrx_pdev, pl_hdr); + +} + +#if defined(QCA_WIFI_3_0_ADRASTEA) +/** + * pktlog_t2h_msg_handler() - Target to host message handler + * @context: pdev context + * @pkt: HTC packet + * + * Return: None + */ +static void pktlog_t2h_msg_handler(void *context, HTC_PACKET *pkt) +{ + struct ol_pktlog_dev_t *pdev = (struct ol_pktlog_dev_t *)context; + qdf_nbuf_t pktlog_t2h_msg = (qdf_nbuf_t) pkt->pPktContext; + uint32_t *msg_word; + + /* check for successful message reception */ + if (pkt->Status != A_OK) { + if (pkt->Status != A_ECANCELED) + pdev->htc_err_cnt++; + qdf_nbuf_free(pktlog_t2h_msg); + return; + } + + /* confirm alignment */ + qdf_assert((((unsigned long)qdf_nbuf_data(pktlog_t2h_msg)) & 0x3) == 0); + + msg_word = (uint32_t *) qdf_nbuf_data(pktlog_t2h_msg); + pktlog_process_fw_msg(msg_word); + + qdf_nbuf_free(pktlog_t2h_msg); +} + +/** + * pktlog_tx_resume_handler() - resume callback + * @context: pdev context + * + * Return: None + */ +static void pktlog_tx_resume_handler(void *context) +{ + qdf_print("%s: Not expected", __func__); + qdf_assert(0); +} + +/** + * pktlog_h2t_send_complete() - send complete indication + * @context: pdev context + * @htc_pkt: HTC packet + * + * Return: None + */ +static void pktlog_h2t_send_complete(void *context, HTC_PACKET *htc_pkt) +{ + qdf_print("%s: Not expected", __func__); + qdf_assert(0); +} + +/** + * pktlog_h2t_full() - queue full indication + * @context: pdev context + * @pkt: HTC packet + * + * Return: HTC action + */ +static HTC_SEND_FULL_ACTION pktlog_h2t_full(void *context, HTC_PACKET *pkt) +{ + return HTC_SEND_FULL_KEEP; +} + +/** + * pktlog_htc_connect_service() - create new endpoint for packetlog + * @pdev - pktlog pdev + * + * Return: 0 for success/failure + */ +static int pktlog_htc_connect_service(struct ol_pktlog_dev_t *pdev) +{ + HTC_SERVICE_CONNECT_REQ connect; + HTC_SERVICE_CONNECT_RESP response; + A_STATUS status; + + qdf_mem_set(&connect, sizeof(connect), 0); + qdf_mem_set(&response, sizeof(response), 0); + + connect.pMetaData = NULL; + connect.MetaDataLength = 0; + connect.EpCallbacks.pContext = pdev; + connect.EpCallbacks.EpTxComplete = pktlog_h2t_send_complete; + connect.EpCallbacks.EpTxCompleteMultiple = NULL; + connect.EpCallbacks.EpRecv = pktlog_t2h_msg_handler; + connect.EpCallbacks.ep_resume_tx_queue = pktlog_tx_resume_handler; + + /* rx buffers currently are provided by HIF, not by EpRecvRefill */ + connect.EpCallbacks.EpRecvRefill = NULL; + connect.EpCallbacks.RecvRefillWaterMark = 1; + /* N/A, fill is done by HIF */ + + connect.EpCallbacks.EpSendFull = pktlog_h2t_full; + /* + * Specify how deep to let a queue get before htc_send_pkt will + * call the EpSendFull function due to excessive send queue depth. + */ + connect.MaxSendQueueDepth = PKTLOG_MAX_SEND_QUEUE_DEPTH; + + /* disable flow control for HTT data message service */ + connect.ConnectionFlags |= HTC_CONNECT_FLAGS_DISABLE_CREDIT_FLOW_CTRL; + + /* connect to control service */ + connect.service_id = PACKET_LOG_SVC; + + status = htc_connect_service(pdev->htc_pdev, &connect, &response); + + if (status != A_OK) { + pdev->mt_pktlog_enabled = false; + return -EIO; /* failure */ + } + + pdev->htc_endpoint = response.Endpoint; + pdev->mt_pktlog_enabled = true; + + return 0; /* success */ +} + +/** + * pktlog_htc_attach() - attach pktlog HTC service + * + * Return: 0 for success/failure + */ +int pktlog_htc_attach(void) +{ + struct ol_txrx_pdev_t *txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_pktlog_dev_t *pdev = NULL; + void *htc_pdev = cds_get_context(QDF_MODULE_ID_HTC); + + if ((!txrx_pdev) || (!txrx_pdev->pl_dev) || (!htc_pdev)) + return -EINVAL; + + pdev = txrx_pdev->pl_dev; + pdev->htc_pdev = htc_pdev; + return pktlog_htc_connect_service(pdev); +} +#else +int pktlog_htc_attach(void) +{ + struct ol_txrx_pdev_t *txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX); + struct ol_pktlog_dev_t *pdev = NULL; + + if (!txrx_pdev) + return -EINVAL; + pdev = txrx_pdev->pl_dev; + pdev->mt_pktlog_enabled = false; + return 0; +} +#endif +#endif /* REMOVE_PKT_LOG */ diff --git a/utils/pktlog/pktlog_internal.c b/utils/pktlog/pktlog_internal.c new file mode 100644 index 0000000000..fb2d2981f5 --- /dev/null +++ b/utils/pktlog/pktlog_internal.c @@ -0,0 +1,871 @@ +/* + * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef REMOVE_PKT_LOG +#include "ol_txrx_types.h" +#include "ol_htt_tx_api.h" +#include "ol_tx_desc.h" +#include "qdf_mem.h" +#include "htt.h" +#include "htt_internal.h" +#include "pktlog_ac_i.h" +#include "wma_api.h" +#include "wlan_logging_sock_svc.h" + +#define TX_DESC_ID_LOW_MASK 0xffff +#define TX_DESC_ID_LOW_SHIFT 0 +#define TX_DESC_ID_HIGH_MASK 0xffff0000 +#define TX_DESC_ID_HIGH_SHIFT 16 + +void pktlog_getbuf_intsafe(struct ath_pktlog_arg *plarg) +{ + struct ath_pktlog_buf *log_buf; + int32_t buf_size; + struct ath_pktlog_hdr *log_hdr; + int32_t cur_wr_offset; + char *log_ptr; + struct ath_pktlog_info *pl_info; + uint16_t log_type; + size_t log_size; + uint32_t flags; +#ifdef HELIUMPLUS + uint8_t mac_id; +#endif + + if (!plarg) { + printk("Invalid parg in %s\n", __func__); + return; + } + + pl_info = plarg->pl_info; +#ifdef HELIUMPLUS + mac_id = plarg->macId; + log_type = plarg->log_type; +#else + log_type = plarg->log_type; +#endif + log_size = plarg->log_size; + log_buf = pl_info->buf; + flags = plarg->flags; + + if (!log_buf) { + printk("Invalid log_buf in %s\n", __func__); + return; + } + buf_size = pl_info->buf_size; + cur_wr_offset = log_buf->wr_offset; + /* Move read offset to the next entry if there is a buffer overlap */ + if (log_buf->rd_offset >= 0) { + if ((cur_wr_offset <= log_buf->rd_offset) + && (cur_wr_offset + sizeof(struct ath_pktlog_hdr)) > + log_buf->rd_offset) { + PKTLOG_MOV_RD_IDX(log_buf->rd_offset, log_buf, + buf_size); + } + } else { + log_buf->rd_offset = cur_wr_offset; + } + + log_hdr = (struct ath_pktlog_hdr *)(log_buf->log_data + cur_wr_offset); + + log_hdr->flags = flags; +#ifdef HELIUMPLUS + log_hdr->macId = mac_id; + log_hdr->log_type = log_type; +#else + log_hdr->log_type = log_type; +#endif + log_hdr->size = (uint16_t) log_size; + log_hdr->missed_cnt = plarg->missed_cnt; + log_hdr->timestamp = plarg->timestamp; +#ifdef HELIUMPLUS + log_hdr->type_specific_data = plarg->type_specific_data; +#endif + cur_wr_offset += sizeof(*log_hdr); + + if ((buf_size - cur_wr_offset) < log_size) { + while ((cur_wr_offset <= log_buf->rd_offset) + && (log_buf->rd_offset < buf_size)) { + PKTLOG_MOV_RD_IDX(log_buf->rd_offset, log_buf, + buf_size); + } + cur_wr_offset = 0; + } + + while ((cur_wr_offset <= log_buf->rd_offset) + && (cur_wr_offset + log_size) > log_buf->rd_offset) { + PKTLOG_MOV_RD_IDX(log_buf->rd_offset, log_buf, buf_size); + } + + log_ptr = &(log_buf->log_data[cur_wr_offset]); + cur_wr_offset += log_hdr->size; + + log_buf->wr_offset = ((buf_size - cur_wr_offset) >= + sizeof(struct ath_pktlog_hdr)) ? cur_wr_offset : + 0; + + plarg->buf = log_ptr; +} + +char *pktlog_getbuf(struct ol_pktlog_dev_t *pl_dev, + struct ath_pktlog_info *pl_info, + size_t log_size, struct ath_pktlog_hdr *pl_hdr) +{ + struct ath_pktlog_arg plarg = { 0, }; + uint8_t flags = 0; + + plarg.pl_info = pl_info; +#ifdef HELIUMPLUS + plarg.macId = pl_hdr->macId; + plarg.log_type = pl_hdr->log_type; +#else + plarg.log_type = pl_hdr->log_type; +#endif + plarg.log_size = log_size; + plarg.flags = pl_hdr->flags; + plarg.missed_cnt = pl_hdr->missed_cnt; + plarg.timestamp = pl_hdr->timestamp; +#ifdef HELIUMPLUS + plarg.type_specific_data = pl_hdr->type_specific_data; +#endif + if (flags & PHFLAGS_INTERRUPT_CONTEXT) { + /* + * We are already in interupt context, no need to make it + * intsafe. call the function directly. + */ + pktlog_getbuf_intsafe(&plarg); + } else { + PKTLOG_LOCK(pl_info); + pktlog_getbuf_intsafe(&plarg); + PKTLOG_UNLOCK(pl_info); + } + + return plarg.buf; +} + +static struct txctl_frm_hdr frm_hdr; + +#ifndef HELIUMPLUS +static void process_ieee_hdr(void *data) +{ + uint8_t dir; + struct ieee80211_frame *wh = (struct ieee80211_frame *)(data); + + frm_hdr.framectrl = *(uint16_t *) (wh->i_fc); + frm_hdr.seqctrl = *(uint16_t *) (wh->i_seq); + dir = (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK); + + if (dir == IEEE80211_FC1_DIR_TODS) { + frm_hdr.bssid_tail = + (wh->i_addr1[IEEE80211_ADDR_LEN - 2] << 8) | (wh-> + i_addr1 + [IEEE80211_ADDR_LEN + - 1]); + frm_hdr.sa_tail = + (wh->i_addr2[IEEE80211_ADDR_LEN - 2] << 8) | (wh-> + i_addr2 + [IEEE80211_ADDR_LEN + - 1]); + frm_hdr.da_tail = + (wh->i_addr3[IEEE80211_ADDR_LEN - 2] << 8) | (wh-> + i_addr3 + [IEEE80211_ADDR_LEN + - 1]); + } else if (dir == IEEE80211_FC1_DIR_FROMDS) { + frm_hdr.bssid_tail = + (wh->i_addr2[IEEE80211_ADDR_LEN - 2] << 8) | (wh-> + i_addr2 + [IEEE80211_ADDR_LEN + - 1]); + frm_hdr.sa_tail = + (wh->i_addr3[IEEE80211_ADDR_LEN - 2] << 8) | (wh-> + i_addr3 + [IEEE80211_ADDR_LEN + - 1]); + frm_hdr.da_tail = + (wh->i_addr1[IEEE80211_ADDR_LEN - 2] << 8) | (wh-> + i_addr1 + [IEEE80211_ADDR_LEN + - 1]); + } else { + frm_hdr.bssid_tail = + (wh->i_addr3[IEEE80211_ADDR_LEN - 2] << 8) | (wh-> + i_addr3 + [IEEE80211_ADDR_LEN + - 1]); + frm_hdr.sa_tail = + (wh->i_addr2[IEEE80211_ADDR_LEN - 2] << 8) | (wh-> + i_addr2 + [IEEE80211_ADDR_LEN + - 1]); + frm_hdr.da_tail = + (wh->i_addr1[IEEE80211_ADDR_LEN - 2] << 8) | (wh-> + i_addr1 + [IEEE80211_ADDR_LEN + - 1]); + } +} + +/** + * fill_ieee80211_hdr_data() - fill ieee802.11 data header + * @txrx_pdev: txrx pdev + * @pl_msdu_info: msdu info + * @data: data received from event + * + * Return: none + */ +static void +fill_ieee80211_hdr_data(struct ol_txrx_pdev_t *txrx_pdev, + struct ath_pktlog_msdu_info *pl_msdu_info, void *data) +{ + uint32_t i; + uint32_t *htt_tx_desc; + struct ol_tx_desc_t *tx_desc; + uint8_t msdu_id_offset = MSDU_ID_INFO_ID_OFFSET; + uint16_t tx_desc_id; + uint32_t *msdu_id_info = (uint32_t *) + ((void *)data + sizeof(struct ath_pktlog_hdr)); + uint32_t *msdu_id = (uint32_t *) ((char *)msdu_id_info + + msdu_id_offset); + uint8_t *addr, *vap_addr; + uint8_t vdev_id; + qdf_nbuf_t netbuf; + uint32_t len; + + + pl_msdu_info->num_msdu = *msdu_id_info; + pl_msdu_info->priv_size = sizeof(uint32_t) * + pl_msdu_info->num_msdu + sizeof(uint32_t); + + for (i = 0; i < pl_msdu_info->num_msdu; i++) { + /* + * Handle big endianness + * Increment msdu_id once after retrieving + * lower 16 bits and uppper 16 bits + */ + if (!(i % 2)) { + tx_desc_id = ((*msdu_id & TX_DESC_ID_LOW_MASK) + >> TX_DESC_ID_LOW_SHIFT); + } else { + tx_desc_id = ((*msdu_id & TX_DESC_ID_HIGH_MASK) + >> TX_DESC_ID_HIGH_SHIFT); + msdu_id += 1; + } + tx_desc = ol_tx_desc_find(txrx_pdev, tx_desc_id); + qdf_assert(tx_desc); + netbuf = tx_desc->netbuf; + htt_tx_desc = (uint32_t *) tx_desc->htt_tx_desc; + qdf_assert(htt_tx_desc); + + qdf_nbuf_peek_header(netbuf, &addr, &len); + + if (len < (2 * IEEE80211_ADDR_LEN)) { + qdf_print("TX frame does not have a valid address\n"); + return; + } + /* Adding header information for the TX data frames */ + vdev_id = (uint8_t) (*(htt_tx_desc + + HTT_TX_VDEV_ID_WORD) >> + HTT_TX_VDEV_ID_SHIFT) & + HTT_TX_VDEV_ID_MASK; + + vap_addr = wma_get_vdev_address_by_vdev_id(vdev_id); + + frm_hdr.da_tail = (addr[IEEE80211_ADDR_LEN - 2] << 8) | + (addr[IEEE80211_ADDR_LEN - 1]); + frm_hdr.sa_tail = + (addr[2 * IEEE80211_ADDR_LEN - 2] << 8) | + (addr[2 * IEEE80211_ADDR_LEN - 1]); + if (vap_addr) { + frm_hdr.bssid_tail = + (vap_addr[IEEE80211_ADDR_LEN - 2] << 8) | + (vap_addr[IEEE80211_ADDR_LEN - 1]); + } else { + frm_hdr.bssid_tail = 0x0000; + } + pl_msdu_info->priv.msdu_len[i] = *(htt_tx_desc + + HTT_TX_MSDU_LEN_DWORD) + & HTT_TX_MSDU_LEN_MASK; + /* + * Add more information per MSDU + * e.g., protocol information + */ + } + +} +#endif + +#ifdef HELIUMPLUS +A_STATUS process_tx_info(struct ol_txrx_pdev_t *txrx_pdev, void *data) +{ + /* + * Must include to process different types + * TX_CTL, TX_STATUS, TX_MSDU_ID, TX_FRM_HDR + */ + struct ol_pktlog_dev_t *pl_dev; + struct ath_pktlog_hdr pl_hdr; + struct ath_pktlog_info *pl_info; + uint32_t *pl_tgt_hdr; + + if (!txrx_pdev) { + printk("Invalid pdev in %s\n", __func__); + return A_ERROR; + } + qdf_assert(txrx_pdev->pl_dev); + qdf_assert(data); + pl_dev = txrx_pdev->pl_dev; + + pl_tgt_hdr = (uint32_t *) data; + /* + * Makes the short words (16 bits) portable b/w little endian + * and big endian + */ + pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & + ATH_PKTLOG_HDR_FLAGS_MASK) >> + ATH_PKTLOG_HDR_FLAGS_SHIFT; + pl_hdr.flags |= PKTLOG_HDR_SIZE_16; + pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & + ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> + ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; + pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) & + ATH_PKTLOG_HDR_MAC_ID_MASK) >> + ATH_PKTLOG_HDR_MAC_ID_SHIFT; + pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & + ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; + pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); + pl_hdr.type_specific_data = + *(pl_tgt_hdr + ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET); + pl_info = pl_dev->pl_info; + + if (pl_hdr.log_type == PKTLOG_TYPE_TX_CTRL) { + size_t log_size = sizeof(frm_hdr) + pl_hdr.size; + void *txdesc_hdr_ctl = (void *) + pktlog_getbuf(pl_dev, pl_info, log_size, &pl_hdr); + qdf_assert(txdesc_hdr_ctl); + qdf_assert(pl_hdr.size < (370 * sizeof(u_int32_t))); + + qdf_mem_copy(txdesc_hdr_ctl, &frm_hdr, sizeof(frm_hdr)); + qdf_mem_copy((char *)txdesc_hdr_ctl + sizeof(frm_hdr), + ((void *)data + + sizeof(struct ath_pktlog_hdr)), + pl_hdr.size); + pl_hdr.size = log_size; + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, + txdesc_hdr_ctl); + } + + if (pl_hdr.log_type == PKTLOG_TYPE_TX_STAT) { + struct ath_pktlog_tx_status txstat_log; + size_t log_size = pl_hdr.size; + + txstat_log.ds_status = (void *) + pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + qdf_assert(txstat_log.ds_status); + qdf_mem_copy(txstat_log.ds_status, + ((void *)data + sizeof(struct ath_pktlog_hdr)), + pl_hdr.size); + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, + txstat_log.ds_status); + } + return A_OK; +} + +#else +A_STATUS process_tx_info(struct ol_txrx_pdev_t *txrx_pdev, void *data) +{ + /* + * Must include to process different types + * TX_CTL, TX_STATUS, TX_MSDU_ID, TX_FRM_HDR + */ + struct ol_pktlog_dev_t *pl_dev; + struct ath_pktlog_hdr pl_hdr; + struct ath_pktlog_info *pl_info; + uint32_t *pl_tgt_hdr; + + if (!txrx_pdev) { + qdf_print("Invalid pdev in %s\n", __func__); + return A_ERROR; + } + qdf_assert(txrx_pdev->pl_dev); + qdf_assert(data); + pl_dev = txrx_pdev->pl_dev; + + pl_tgt_hdr = (uint32_t *) data; + /* + * Makes the short words (16 bits) portable b/w little endian + * and big endian + */ + pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & + ATH_PKTLOG_HDR_FLAGS_MASK) >> + ATH_PKTLOG_HDR_FLAGS_SHIFT; + pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & + ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> + ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; + pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & + ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; + pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); + + pl_info = pl_dev->pl_info; + + if (pl_hdr.log_type == PKTLOG_TYPE_TX_FRM_HDR) { + /* Valid only for the TX CTL */ + process_ieee_hdr(data + sizeof(pl_hdr)); + } + + if (pl_hdr.log_type == PKTLOG_TYPE_TX_VIRT_ADDR) { + A_UINT32 desc_id = (A_UINT32) + *((A_UINT32 *) (data + sizeof(pl_hdr))); + A_UINT32 vdev_id = desc_id; + + /* if the pkt log msg is for the bcn frame the vdev id + * is piggybacked in desc_id and the MSB of the desc ID + * would be set to FF + */ +#define BCN_DESC_ID 0xFF + if ((desc_id >> 24) == BCN_DESC_ID) { + void *data; + A_UINT32 buf_size; + + vdev_id &= 0x00FFFFFF; + data = wma_get_beacon_buffer_by_vdev_id(vdev_id, + &buf_size); + if (data) { + process_ieee_hdr(data); + qdf_mem_free(data); + } + } else { + /* + * TODO: get the hdr content for mgmt frames from + * Tx mgmt desc pool + */ + } + } + + if (pl_hdr.log_type == PKTLOG_TYPE_TX_CTRL) { + struct ath_pktlog_txctl txctl_log; + size_t log_size = sizeof(txctl_log.priv); + + txctl_log.txdesc_hdr_ctl = (void *)pktlog_getbuf(pl_dev, + pl_info, + log_size, + &pl_hdr); + + if (!txctl_log.txdesc_hdr_ctl) { + printk + ("failed to get buf for txctl_log.txdesc_hdr_ctl\n"); + return A_ERROR; + } + + /* + * frm hdr is currently Valid only for local frames + * Add capability to include the fmr hdr for remote frames + */ + txctl_log.priv.frm_hdr = frm_hdr; + qdf_assert(txctl_log.priv.txdesc_ctl); + qdf_mem_copy((void *)&txctl_log.priv.txdesc_ctl, + ((void *)data + sizeof(struct ath_pktlog_hdr)), + pl_hdr.size); + qdf_assert(txctl_log.txdesc_hdr_ctl); + qdf_mem_copy(txctl_log.txdesc_hdr_ctl, &txctl_log.priv, + sizeof(txctl_log.priv)); + pl_hdr.size = log_size; + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, + txctl_log.txdesc_hdr_ctl); + /* Add Protocol information and HT specific information */ + } + + if (pl_hdr.log_type == PKTLOG_TYPE_TX_STAT) { + struct ath_pktlog_tx_status txstat_log; + size_t log_size = pl_hdr.size; + + txstat_log.ds_status = (void *) + pktlog_getbuf(pl_dev, pl_info, log_size, &pl_hdr); + qdf_assert(txstat_log.ds_status); + qdf_mem_copy(txstat_log.ds_status, + ((void *)data + sizeof(struct ath_pktlog_hdr)), + pl_hdr.size); + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, + txstat_log.ds_status); + } + + if (pl_hdr.log_type == PKTLOG_TYPE_TX_MSDU_ID) { + struct ath_pktlog_msdu_info pl_msdu_info; + size_t log_size; + + qdf_mem_set(&pl_msdu_info, sizeof(pl_msdu_info), 0); + log_size = sizeof(pl_msdu_info.priv); + + if (pl_dev->mt_pktlog_enabled == false) + fill_ieee80211_hdr_data(txrx_pdev, &pl_msdu_info, data); + + pl_msdu_info.ath_msdu_info = pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + qdf_mem_copy((void *)&pl_msdu_info.priv.msdu_id_info, + ((void *)data + sizeof(struct ath_pktlog_hdr)), + sizeof(pl_msdu_info.priv.msdu_id_info)); + qdf_mem_copy(pl_msdu_info.ath_msdu_info, &pl_msdu_info.priv, + sizeof(pl_msdu_info.priv)); + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, + pl_msdu_info.ath_msdu_info); + } + return A_OK; +} +#endif + +A_STATUS process_rx_info_remote(void *pdev, void *data) +{ + struct ol_pktlog_dev_t *pl_dev; + struct ath_pktlog_info *pl_info; + struct htt_host_rx_desc_base *rx_desc; + struct ath_pktlog_hdr pl_hdr; + struct ath_pktlog_rx_info rxstat_log; + size_t log_size; + struct ol_rx_remote_data *r_data = (struct ol_rx_remote_data *)data; + qdf_nbuf_t msdu; + + if (!pdev) { + printk("Invalid pdev in %s\n", __func__); + return A_ERROR; + } + if (!r_data) { + printk("Invalid data in %s\n", __func__); + return A_ERROR; + } + pl_dev = ((struct ol_txrx_pdev_t *)pdev)->pl_dev; + pl_info = pl_dev->pl_info; + msdu = r_data->msdu; + + while (msdu) { + rx_desc = + (struct htt_host_rx_desc_base *)(qdf_nbuf_data(msdu)) - 1; + log_size = + sizeof(*rx_desc) - sizeof(struct htt_host_fw_desc_base); + + /* + * Construct the pktlog header pl_hdr + * Because desc is DMA'd to the host memory + */ + pl_hdr.flags = (1 << PKTLOG_FLG_FRM_TYPE_REMOTE_S); + pl_hdr.missed_cnt = 0; +#if defined(HELIUMPLUS) + pl_hdr.macId = r_data->mac_id; + pl_hdr.log_type = PKTLOG_TYPE_RX_STAT; + pl_hdr.flags |= PKTLOG_HDR_SIZE_16; +#else + pl_hdr.log_type = PKTLOG_TYPE_RX_STAT; +#endif + pl_hdr.size = sizeof(*rx_desc) - + sizeof(struct htt_host_fw_desc_base); +#if defined(HELIUMPLUS) + pl_hdr.timestamp = + rx_desc->ppdu_end.rx_pkt_end.phy_timestamp_1_lower_32; + pl_hdr.type_specific_data = 0xDEADAA; +#else + pl_hdr.timestamp = rx_desc->ppdu_end.tsf_timestamp; +#endif /* !defined(HELIUMPLUS) */ + rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + qdf_mem_copy(rxstat_log.rx_desc, (void *)rx_desc + + sizeof(struct htt_host_fw_desc_base), pl_hdr.size); + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, + rxstat_log.rx_desc); + msdu = qdf_nbuf_next(msdu); + } + return A_OK; +} + +A_STATUS process_rx_info(void *pdev, void *data) +{ + struct ol_pktlog_dev_t *pl_dev; + struct ath_pktlog_info *pl_info; + struct ath_pktlog_rx_info rxstat_log; + struct ath_pktlog_hdr pl_hdr; + size_t log_size; + uint32_t *pl_tgt_hdr; + + if (!pdev) { + printk("Invalid pdev in %s", __func__); + return A_ERROR; + } + pl_dev = ((struct ol_txrx_pdev_t *)pdev)->pl_dev; + pl_info = pl_dev->pl_info; + pl_tgt_hdr = (uint32_t *) data; + pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & + ATH_PKTLOG_HDR_FLAGS_MASK) >> + ATH_PKTLOG_HDR_FLAGS_SHIFT; + pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & + ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> + ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; +#ifdef HELIUMPLUS + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; + pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) & + ATH_PKTLOG_HDR_MAC_ID_MASK) >> + ATH_PKTLOG_HDR_MAC_ID_SHIFT; + pl_hdr.flags |= PKTLOG_HDR_SIZE_16; +#else + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; +#endif + + pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & + ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; + pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); + log_size = pl_hdr.size; + rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + + qdf_mem_copy(rxstat_log.rx_desc, + (void *)data + sizeof(struct ath_pktlog_hdr), pl_hdr.size); + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rxstat_log.rx_desc); + + return A_OK; +} + +A_STATUS process_rate_find(void *pdev, void *data) +{ + struct ol_pktlog_dev_t *pl_dev; + struct ath_pktlog_hdr pl_hdr; + struct ath_pktlog_info *pl_info; + size_t log_size; + + /* + * Will be uncommented when the rate control find + * for pktlog is implemented in the firmware. + * Currently derived from the TX PPDU status + */ + struct ath_pktlog_rc_find rcf_log; + uint32_t *pl_tgt_hdr; + + if (!pdev) { + qdf_print("Invalid pdev in %s\n", __func__); + return A_ERROR; + } + if (!data) { + qdf_print("Invalid data in %s\n", __func__); + return A_ERROR; + } + + pl_tgt_hdr = (uint32_t *) data; + /* + * Makes the short words (16 bits) portable b/w little endian + * and big endian + */ + pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & + ATH_PKTLOG_HDR_FLAGS_MASK) >> + ATH_PKTLOG_HDR_FLAGS_SHIFT; + pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & + ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> + ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; +#ifdef HELIUMPLUS + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; + pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) & + ATH_PKTLOG_HDR_MAC_ID_MASK) >> + ATH_PKTLOG_HDR_MAC_ID_SHIFT; + pl_hdr.flags |= PKTLOG_HDR_SIZE_16; +#else + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; +#endif + + pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & + ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; + pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); + pl_dev = ((struct ol_txrx_pdev_t *)pdev)->pl_dev; + pl_info = pl_dev->pl_info; + log_size = pl_hdr.size; + rcf_log.rcFind = (void *)pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + + qdf_mem_copy(rcf_log.rcFind, + ((char *)data + sizeof(struct ath_pktlog_hdr)), + pl_hdr.size); + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rcf_log.rcFind); + + return A_OK; +} + +A_STATUS process_sw_event(void *pdev, void *data) +{ + struct ol_pktlog_dev_t *pl_dev; + struct ath_pktlog_hdr pl_hdr; + struct ath_pktlog_info *pl_info; + size_t log_size; + + /* + * Will be uncommented when the rate control find + * for pktlog is implemented in the firmware. + * Currently derived from the TX PPDU status + */ + struct ath_pktlog_sw_event sw_event; + uint32_t *pl_tgt_hdr; + + if (!pdev) { + qdf_print("Invalid pdev in %s\n", __func__); + return A_ERROR; + } + if (!data) { + qdf_print("Invalid data in %s\n", __func__); + return A_ERROR; + } + + pl_tgt_hdr = (uint32_t *) data; + /* + * Makes the short words (16 bits) portable b/w little endian + * and big endian + */ + pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & + ATH_PKTLOG_HDR_FLAGS_MASK) >> + ATH_PKTLOG_HDR_FLAGS_SHIFT; + pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & + ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> + ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; +#ifdef HELIUMPLUS + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; + pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) & + ATH_PKTLOG_HDR_MAC_ID_MASK) >> + ATH_PKTLOG_HDR_MAC_ID_SHIFT; +#else + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; +#endif + + pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & + ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; + pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); + +#ifdef HELIUMPLUS + pl_hdr.type_specific_data = + *(pl_tgt_hdr + ATH_PKTLOG_HDR_TYPE_SPECIFIC_DATA_OFFSET); +#endif + + pl_dev = ((struct ol_txrx_pdev_t *)pdev)->pl_dev; + pl_info = pl_dev->pl_info; + log_size = pl_hdr.size; + sw_event.sw_event = (void *)pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + + qdf_mem_copy(sw_event.sw_event, + ((char *)data + sizeof(struct ath_pktlog_hdr)), + pl_hdr.size); + + return A_OK; +} + +A_STATUS process_rate_update(void *pdev, void *data) +{ + struct ol_pktlog_dev_t *pl_dev; + struct ath_pktlog_hdr pl_hdr; + size_t log_size; + struct ath_pktlog_info *pl_info; + struct ath_pktlog_rc_update rcu_log; + uint32_t *pl_tgt_hdr; + + if (!pdev) { + printk("Invalid pdev in %s\n", __func__); + return A_ERROR; + } + if (!data) { + printk("Invalid data in %s\n", __func__); + return A_ERROR; + } + pl_tgt_hdr = (uint32_t *) data; + /* + * Makes the short words (16 bits) portable b/w little endian + * and big endian + */ + pl_hdr.flags = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_FLAGS_OFFSET) & + ATH_PKTLOG_HDR_FLAGS_MASK) >> + ATH_PKTLOG_HDR_FLAGS_SHIFT; + pl_hdr.missed_cnt = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MISSED_CNT_OFFSET) & + ATH_PKTLOG_HDR_MISSED_CNT_MASK) >> + ATH_PKTLOG_HDR_MISSED_CNT_SHIFT; +#ifdef HELIUMPLUS + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; + pl_hdr.macId = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_MAC_ID_OFFSET) & + ATH_PKTLOG_HDR_MAC_ID_MASK) >> + ATH_PKTLOG_HDR_MAC_ID_SHIFT; + pl_hdr.flags |= PKTLOG_HDR_SIZE_16; +#else + pl_hdr.log_type = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_LOG_TYPE_OFFSET) & + ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> + ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; +#endif + + pl_hdr.size = (*(pl_tgt_hdr + ATH_PKTLOG_HDR_SIZE_OFFSET) & + ATH_PKTLOG_HDR_SIZE_MASK) >> ATH_PKTLOG_HDR_SIZE_SHIFT; + pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET); + pl_dev = ((struct ol_txrx_pdev_t *)pdev)->pl_dev; + log_size = pl_hdr.size; + pl_info = pl_dev->pl_info; + + /* + * Will be uncommented when the rate control update + * for pktlog is implemented in the firmware. + * Currently derived from the TX PPDU status + */ + rcu_log.txRateCtrl = (void *)pktlog_getbuf(pl_dev, pl_info, + log_size, &pl_hdr); + qdf_mem_copy(rcu_log.txRateCtrl, + ((char *)data + sizeof(struct ath_pktlog_hdr)), + pl_hdr.size); + cds_pkt_stats_to_logger_thread(&pl_hdr, NULL, rcu_log.txRateCtrl); + return A_OK; +} +#endif /*REMOVE_PKT_LOG */ diff --git a/utils/ptt/inc/wlan_ptt_sock_svc.h b/utils/ptt/inc/wlan_ptt_sock_svc.h new file mode 100644 index 0000000000..7c1077be51 --- /dev/null +++ b/utils/ptt/inc/wlan_ptt_sock_svc.h @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** +* wlan_ptt_sock_svc.c +* +******************************************************************************/ +#ifndef PTT_SOCK_SVC_H +#define PTT_SOCK_SVC_H +#include +#include +#include +#include + +/* + * Quarky Message Format: + * The following is the messaging protocol between Quarky and PTT Socket App. + * The totalMsgLen is the length from Radio till msgBody. The value of Radio + * is always defaulted to 0. The MsgLen is the length from msgId till msgBody. + * The length of the msgBody varies with respect to the MsgId. Buffer space + * for MsgBody is already allocated in the received buffer. So in case of READ + * we just need to populate the values in the received message and send it + * back + * +------------+-------+-------+--------+-------+---------+ + * |TotalMsgLen | Radio | MsgId | MsgLen |Status |MsgBody | + * +------------+-------+-------|--------+-------+---------+ + * <------4----><--4---><---2--><---2---><---4--><---------> + */ +/* PTT Socket App Message Ids */ +#define PTT_MSG_READ_REGISTER 0x3040 +#define PTT_MSG_WRITE_REGISTER 0x3041 +#define PTT_MSG_READ_MEMORY 0x3044 +#define PTT_MSG_WRITE_MEMORY 0x3045 +#define PTT_MSG_LOG_DUMP_DBG 0x32A1 +#define PTT_MSG_FTM_CMDS_TYPE 0x4040 +#define ANI_DRIVER_MSG_START 0x0001 +#define ANI_MSG_APP_REG_REQ (ANI_DRIVER_MSG_START + 0) +#define ANI_MSG_APP_REG_RSP (ANI_DRIVER_MSG_START + 1) +#define ANI_MSG_OEM_DATA_REQ (ANI_DRIVER_MSG_START + 2) +#define ANI_MSG_OEM_DATA_RSP (ANI_DRIVER_MSG_START + 3) +#define ANI_MSG_CHANNEL_INFO_REQ (ANI_DRIVER_MSG_START + 4) +#define ANI_MSG_CHANNEL_INFO_RSP (ANI_DRIVER_MSG_START + 5) +#define ANI_MSG_OEM_ERROR (ANI_DRIVER_MSG_START + 6) +#define ANI_MSG_PEER_STATUS_IND (ANI_DRIVER_MSG_START + 7) +#define ANI_MSG_SET_OEM_CAP_REQ (ANI_DRIVER_MSG_START + 8) +#define ANI_MSG_SET_OEM_CAP_RSP (ANI_DRIVER_MSG_START + 9) +#define ANI_MSG_GET_OEM_CAP_REQ (ANI_DRIVER_MSG_START + 10) +#define ANI_MSG_GET_OEM_CAP_RSP (ANI_DRIVER_MSG_START + 11) + +#define ANI_MAX_RADIOS 3 +#define ANI_NL_MSG_OK 0 +#define ANI_NL_MSG_ERROR -1 +#define ANI_NL_MSG_OVERHEAD (NLMSG_SPACE(tAniHdr + 4)) +/* + * Packet Format for READ_REGISTER & WRITE_REGISTER: + * TotalMsgLen : 4 bytes [value=20 bytes] + * Radio : 4 bytes + * MsgId : 2 bytes + * MsgLen : 2 bytes + * Status : 4 bytes + * Address : 4 bytes + * Payload : 4 bytes + */ +/* + * Packet Format for READ_MEMORY & WRITE_MEMORY : + * TotalMsgLen : 4 bytes [value= 20+LEN_PAYLOAD bytes] + * Radio : 4 bytes + * MsgId : 2 bytes + * MsgLen : 2 bytes + * Status : 4 bytes + * Address : 4 bytes + * Length : 4 bytes [LEN_PAYLOAD] + * Payload : LEN_PAYLOAD bytes + */ +#ifdef PTT_SOCK_SVC_ENABLE +int ptt_sock_activate_svc(void); +void ptt_sock_deactivate_svc(void); +int ptt_sock_send_msg_to_app(tAniHdr *wmsg, int radio, int src_mod, int pid); +#else +static inline int ptt_sock_activate_svc(void) { return 0; } +static inline void ptt_sock_deactivate_svc(void) { return; } +static inline int ptt_sock_send_msg_to_app(tAniHdr *wmsg, int radio, + int src_mod, int pid) +{ + return 0; +} +#endif + +/* + * Format of message exchanged between the PTT Socket App in userspace and the + * WLAN Driver, in either direction. Each msg will begin with this header and + * will followed by the Quarky message + */ +typedef struct sAniAppRegReq { + tAniNlModTypes type; /* module id */ + int pid; /* process id */ +} tAniNlAppRegReq; +typedef struct sAniNlAppRegRsp { + tAniHdr wniHdr; /* Generic WNI msg header */ + tAniNlAppRegReq regReq; /* The original request msg */ + int ret; /* Return code */ +} tAniNlAppRegRsp; +#endif diff --git a/utils/ptt/src/wlan_ptt_sock_svc.c b/utils/ptt/src/wlan_ptt_sock_svc.c new file mode 100644 index 0000000000..b000d82acb --- /dev/null +++ b/utils/ptt/src/wlan_ptt_sock_svc.c @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** +* wlan_ptt_sock_svc.c +* +******************************************************************************/ +#ifdef PTT_SOCK_SVC_ENABLE +#include +#include +#include +#include +#include +#include +#include +#include + +#define PTT_SOCK_DEBUG +#ifdef PTT_SOCK_DEBUG +#define PTT_TRACE(level, args ...) QDF_TRACE(QDF_MODULE_ID_QDF, level, ## args) +#else +#define PTT_TRACE(level, args ...) +#endif + +/** ptt Process ID */ +static int32_t ptt_pid = INVALID_PID; + +#ifdef PTT_SOCK_DEBUG_VERBOSE +/* Utility function to perform a hex dump */ +static void ptt_sock_dump_buf(const unsigned char *pbuf, int cnt) +{ + int i; + for (i = 0; i < cnt; i++) { + if ((i % 16) == 0) + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO, + "\n%p:", pbuf); + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO, " %02X", + *pbuf); + pbuf++; + } + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO, "\n"); +} +#endif + +/** + * ptt_sock_send_msg_to_app() - Send nl message to user space + * wmsg: Message header + * radio: Unit number of the radio + * src_mod: Message type + * pid: Process ID to which message will be unicast. Message + * will be broadcast when PID is INVALID_PID + * + * Utility function to send a netlink message to an application in user space + * + * Return: 0 on success and negative value on failure + */ +int ptt_sock_send_msg_to_app(tAniHdr *wmsg, int radio, int src_mod, int pid) +{ + int err = -1; + int payload_len; + int tot_msg_len; + tAniNlHdr *wnl; + struct sk_buff *skb; + struct nlmsghdr *nlh; + int wmsg_length = be16_to_cpu(wmsg->length); + static int nlmsg_seq; + + if (radio < 0 || radio > ANI_MAX_RADIOS) { + PTT_TRACE(QDF_TRACE_LEVEL_ERROR, "%s: invalid radio id [%d]\n", + __func__, radio); + return -EINVAL; + } + payload_len = wmsg_length + sizeof(wnl->radio) + sizeof(*wmsg); + tot_msg_len = NLMSG_SPACE(payload_len); + skb = dev_alloc_skb(tot_msg_len); + if (skb == NULL) { + PTT_TRACE(QDF_TRACE_LEVEL_ERROR, + "%s: dev_alloc_skb() failed for msg size[%d]\n", + __func__, tot_msg_len); + return -ENOMEM; + } + nlh = + nlmsg_put(skb, pid, nlmsg_seq++, src_mod, payload_len, + NLM_F_REQUEST); + if (NULL == nlh) { + PTT_TRACE(QDF_TRACE_LEVEL_ERROR, + "%s: nlmsg_put() failed for msg size[%d]\n", __func__, + tot_msg_len); + kfree_skb(skb); + return -ENOMEM; + } + wnl = (tAniNlHdr *) nlh; + wnl->radio = radio; + memcpy(&wnl->wmsg, wmsg, wmsg_length); +#ifdef PTT_SOCK_DEBUG_VERBOSE + ptt_sock_dump_buf((const unsigned char *)skb->data, skb->len); +#endif + + if (pid != INVALID_PID) + err = nl_srv_ucast(skb, pid, MSG_DONTWAIT); + else + err = nl_srv_bcast(skb); + + if (err) + PTT_TRACE(QDF_TRACE_LEVEL_INFO, + "%s:Failed sending Msg Type [0x%X] to pid[%d]\n", + __func__, be16_to_cpu(wmsg->type), pid); + return err; +} + +/* + * Process tregisteration request and send registration response messages + * to the PTT Socket App in user space + */ +static void ptt_sock_proc_reg_req(tAniHdr *wmsg, int radio) +{ + tAniNlAppRegReq *reg_req; + tAniNlAppRegRsp rspmsg; + reg_req = (tAniNlAppRegReq *) (wmsg + 1); + memset((char *)&rspmsg, 0, sizeof(rspmsg)); + /* send reg response message to the application */ + rspmsg.ret = ANI_NL_MSG_OK; + rspmsg.regReq.type = reg_req->type; + /*Save the pid */ + ptt_pid = reg_req->pid; + rspmsg.regReq.pid = reg_req->pid; + rspmsg.wniHdr.type = cpu_to_be16(ANI_MSG_APP_REG_RSP); + rspmsg.wniHdr.length = cpu_to_be16(sizeof(rspmsg)); + if (ptt_sock_send_msg_to_app((tAniHdr *) &rspmsg.wniHdr, radio, + ANI_NL_MSG_PUMAC, ptt_pid) < 0) { + PTT_TRACE(QDF_TRACE_LEVEL_INFO, + "%s: Error sending ANI_MSG_APP_REG_RSP to pid[%d]\n", + __func__, ptt_pid); + } +} + +/* + * Process all the messages from the PTT Socket App in user space + */ +static void ptt_proc_pumac_msg(struct sk_buff *skb, tAniHdr *wmsg, int radio) +{ + u16 ani_msg_type = be16_to_cpu(wmsg->type); + switch (ani_msg_type) { + case ANI_MSG_APP_REG_REQ: + PTT_TRACE(QDF_TRACE_LEVEL_INFO, + "%s: Received ANI_MSG_APP_REG_REQ [0x%X]\n", __func__, + ani_msg_type); + ptt_sock_proc_reg_req(wmsg, radio); + break; + default: + PTT_TRACE(QDF_TRACE_LEVEL_ERROR, + "%s: Received Unknown Msg Type[0x%X]\n", __func__, + ani_msg_type); + break; + } +} + +/* + * Process all the Netlink messages from PTT Socket app in user space + */ +static int ptt_sock_rx_nlink_msg(struct sk_buff *skb) +{ + tAniNlHdr *wnl; + int radio; + int type; + wnl = (tAniNlHdr *) skb->data; + radio = wnl->radio; + type = wnl->nlh.nlmsg_type; + switch (type) { + case ANI_NL_MSG_PUMAC: /* Message from the PTT socket APP */ + PTT_TRACE(QDF_TRACE_LEVEL_INFO, + "%s: Received ANI_NL_MSG_PUMAC Msg [0x%X]\n", + __func__, type); + ptt_proc_pumac_msg(skb, &wnl->wmsg, radio); + break; + default: + PTT_TRACE(QDF_TRACE_LEVEL_ERROR, "%s: Unknown NL Msg [0x%X]\n", + __func__, type); + break; + } + return 0; +} + +/** + * ptt_sock_activate_svc() - activate PTT service + * + * Return: 0 + */ +int ptt_sock_activate_svc(void) +{ + ptt_pid = INVALID_PID; + nl_srv_register(ANI_NL_MSG_PUMAC, ptt_sock_rx_nlink_msg); + nl_srv_register(ANI_NL_MSG_PTT, ptt_sock_rx_nlink_msg); + return 0; +} + +/** + * ptt_sock_deactivate_svc() - deactivate PTT service + * + * Return: Void + */ +void ptt_sock_deactivate_svc(void) +{ + ptt_pid = INVALID_PID; +} + +#endif /* PTT_SOCK_SVC_ENABLE */