diff options
| author | Padma, Santhosh Kumar <skpadma@codeaurora.org> | 2016-08-11 16:30:25 +0530 |
|---|---|---|
| committer | qcabuildsw <qcabuildsw@localhost> | 2016-10-07 12:54:36 -0700 |
| commit | 9aba02f52c9b4a0bac618e5b3974a8d19bd2d7ac (patch) | |
| tree | 9501cd7bfad42ff6829073feb54aaa78be8479bb | |
| parent | c846f3a36a4a0acb20551964b54826c7c460e863 (diff) | |
qcacld-3.0: Dump driver information
qcacld-2.0 to qcacld-3.0 propagation
Dump state information of HDD, SME, PE and WMA layers
into a buffer. Contents of this buffer will be copied
into user space using proc entry /proc/debugdriver/
driverdump.
Change-Id: Ifbb102e440d7df20defa1a397964cb9b55082bf9
CRs-Fixed: 955357
| -rw-r--r-- | core/cds/src/cds_api.c | 1 | ||||
| -rw-r--r-- | core/hdd/inc/wlan_hdd_main.h | 2 | ||||
| -rw-r--r-- | core/hdd/inc/wlan_hdd_memdump.h | 18 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_main.c | 76 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_memdump.c | 234 | ||||
| -rw-r--r-- | core/mac/src/pe/lim/lim_api.c | 59 | ||||
| -rw-r--r-- | core/sme/src/common/sme_api.c | 99 | ||||
| -rw-r--r-- | core/wma/src/wma_main.c | 142 |
8 files changed, 631 insertions, 0 deletions
diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c index 0e6974a782ee..43a8ea336611 100644 --- a/core/cds/src/cds_api.c +++ b/core/cds/src/cds_api.c @@ -101,6 +101,7 @@ v_CONTEXT_t cds_init(void) #if defined(TRACE_RECORD) qdf_trace_init(); #endif + qdf_register_debugcb_init(); cds_ssr_protect_init(); diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 16dcc8cc01b4..6f263d2b1b64 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1469,6 +1469,8 @@ struct hdd_context_s { bool memdump_in_progress; bool memdump_init_done; #endif /* WLAN_FEATURE_MEMDUMP */ + uint16_t driver_dump_size; + uint8_t *driver_dump_mem; bool connection_in_progress; qdf_spinlock_t connection_status_lock; diff --git a/core/hdd/inc/wlan_hdd_memdump.h b/core/hdd/inc/wlan_hdd_memdump.h index 529f4c772380..5e670fe72785 100644 --- a/core/hdd/inc/wlan_hdd_memdump.h +++ b/core/hdd/inc/wlan_hdd_memdump.h @@ -37,6 +37,10 @@ #include "wlan_hdd_main.h" +/* Assigned size of driver memory dump is 4096 bytes */ +#define DRIVER_MEM_DUMP_SIZE 4096 + + #ifdef WLAN_FEATURE_MEMDUMP /** * enum qca_wlan_vendor_attr_memory_dump - values for memory dump attributes @@ -72,6 +76,10 @@ int wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len); void wlan_hdd_cfg80211_fw_mem_dump_cb(void *ctx, struct fw_dump_rsp *dump_rsp); + +int hdd_driver_memdump_init(void); +void hdd_driver_memdump_deinit(void); + #else static inline int memdump_init(void) { @@ -95,6 +103,16 @@ static inline void wlan_hdd_cfg80211_fw_mem_dump_cb(void *ctx, *dump_rsp) { } + +static inline int hdd_driver_memdump_init(void) +{ + return -ENOTSUPP; +} + +static inline void hdd_driver_memdump_deinit(void) +{ +} + #endif #endif /* if !defined(WLAN_HDD_MEMDUMP_H)*/ diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 47b3c6470000..fda3035e02ab 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -4795,6 +4795,7 @@ void __hdd_wlan_exit(void) hdd_ipa_uc_force_pipe_shutdown(hdd_ctx); memdump_deinit(); + hdd_driver_memdump_deinit(); /* Do all the cleanup before deregistering the driver */ hdd_wlan_exit(hdd_ctx); @@ -7724,6 +7725,79 @@ static void hdd_iface_change_callback(void *priv) } /** + * hdd_state_info_dump() - prints state information of hdd layer + * @buf: buffer pointer + * @size: size of buffer to be filled + * + * This function is used to dump state information of hdd layer + * + * Return: None + */ +static void hdd_state_info_dump(char **buf_ptr, uint16_t *size) +{ + hdd_context_t *hdd_ctx; + hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL; + QDF_STATUS status; + hdd_station_ctx_t *hdd_sta_ctx; + hdd_adapter_t *adapter; + uint16_t len = 0; + char *buf = *buf_ptr; + + hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + if (!hdd_ctx) { + hdd_err("Failed to get hdd context "); + return; + } + + hdd_notice("size of buffer: %d", *size); + + len += scnprintf(buf + len, *size - len, + "\n isWiphySuspended %d", hdd_ctx->isWiphySuspended); + len += scnprintf(buf + len, *size - len, + "\n isMcThreadSuspended %d", + hdd_ctx->isMcThreadSuspended); + + status = hdd_get_front_adapter(hdd_ctx, &adapter_node); + + while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) { + adapter = adapter_node->pAdapter; + if (adapter->dev) + len += scnprintf(buf + len, *size - len, + "\n device name: %s", adapter->dev->name); + len += scnprintf(buf + len, *size - len, + "\n device_mode: %d", adapter->device_mode); + switch (adapter->device_mode) { + case QDF_STA_MODE: + case QDF_P2P_CLIENT_MODE: + hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + len += scnprintf(buf + len, *size - len, + "\n connState: %d", + hdd_sta_ctx->conn_info.connState); + break; + + default: + break; + } + status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next); + adapter_node = next; + } + + *size -= len; + *buf_ptr += len; +} + +/** + * hdd_register_debug_callback() - registration function for hdd layer + * to print hdd state information + * + * Return: None + */ +static void hdd_register_debug_callback(void) +{ + qdf_register_debug_callback(QDF_MODULE_ID_HDD, &hdd_state_info_dump); +} + +/** * hdd_wlan_startup() - HDD init function * @dev: Pointer to the underlying device * @@ -7854,6 +7928,7 @@ int hdd_wlan_startup(struct device *dev) memdump_init(); hdd_encrypt_decrypt_init(hdd_ctx); + hdd_driver_memdump_init(); if (hdd_ctx->config->fIsImpsEnabled) hdd_set_idle_ps_config(hdd_ctx, true); @@ -8804,6 +8879,7 @@ int hdd_init(void) } hdd_trace_init(); + hdd_register_debug_callback(); err_out: return ret; diff --git a/core/hdd/src/wlan_hdd_memdump.c b/core/hdd/src/wlan_hdd_memdump.c index 1afe3fd7569c..195d066018b2 100644 --- a/core/hdd/src/wlan_hdd_memdump.c +++ b/core/hdd/src/wlan_hdd_memdump.c @@ -630,3 +630,237 @@ void memdump_deinit(void) if (!QDF_IS_STATUS_SUCCESS(qdf_status)) hdd_err("Failed to deallocate timer"); } + +#ifdef MULTI_IF_NAME +#define PROCFS_DRIVER_DUMP_DIR "debugdriver" MULTI_IF_NAME +#else +#define PROCFS_DRIVER_DUMP_DIR "debugdriver" +#endif +#define PROCFS_DRIVER_DUMP_NAME "driverdump" +#define PROCFS_DRIVER_DUMP_PERM 0444 + +static struct proc_dir_entry *proc_file_driver, *proc_dir_driver; + +/** + * hdd_driver_mem_cleanup() - Frees memory allocated for + * driver dump + * + * This function unallocates driver dump memory. + * + * Return: None + */ +static void hdd_driver_mem_cleanup(void) +{ + hdd_context_t *hdd_ctx; + + hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + if (!hdd_ctx) { + hdd_err("Invalid HDD context"); + return; + } + + if (hdd_ctx->driver_dump_mem) { + qdf_mem_free(hdd_ctx->driver_dump_mem); + hdd_ctx->driver_dump_mem = NULL; + } +} + + +/** + * hdd_driver_memdump_read() - perform read operation in driver + * memory dump proc file + * @file - handle for the proc file. + * @buf - pointer to user space buffer. + * @count - number of bytes to be read. + * @pos - offset in the from buffer. + * + * This function performs read operation for the driver memory dump proc file. + * + * Return: number of bytes read on success, error code otherwise. + */ +static ssize_t hdd_driver_memdump_read(struct file *file, char __user *buf, + size_t count, loff_t *pos) +{ + int status; + QDF_STATUS qdf_status; + hdd_context_t *hdd_ctx; + size_t no_of_bytes_read = 0; + + hdd_ctx = memdump_get_file_data(file); + + hdd_notice("Read req for size:%zu pos:%llu", count, *pos); + status = wlan_hdd_validate_context(hdd_ctx); + if (status != 0) + return -EINVAL; + + if (*pos < 0) { + hdd_err("Invalid start offset for memdump read"); + return -EINVAL; + } else if (!count || (hdd_ctx->driver_dump_size && + (*pos >= hdd_ctx->driver_dump_size))) { + hdd_err("No more data to copy"); + return 0; + } else if ((*pos == 0) || (hdd_ctx->driver_dump_mem == NULL)) { + /* + * Allocate memory for Driver memory dump. + */ + if (!hdd_ctx->driver_dump_mem) { + hdd_ctx->driver_dump_mem = + qdf_mem_malloc(DRIVER_MEM_DUMP_SIZE); + if (!hdd_ctx->driver_dump_mem) { + hdd_err("qdf_mem_malloc failed"); + return -ENOMEM; + } + } + + qdf_status = qdf_state_info_dump_all(hdd_ctx->driver_dump_mem, + DRIVER_MEM_DUMP_SIZE, + &hdd_ctx->driver_dump_size); + /* + * If qdf_status is QDF_STATUS_E_NOMEM, then memory allocated is + * insufficient to dump driver information. This print can give + * information to allocate more memory if more information from + * each layer is added in future. + */ + if (qdf_status != QDF_STATUS_SUCCESS) + hdd_err("Error in dump driver information, status %d", + qdf_status); + hdd_notice("driver_dump_size: %d", + hdd_ctx->driver_dump_size); + } + + if (count > hdd_ctx->driver_dump_size - *pos) + no_of_bytes_read = hdd_ctx->driver_dump_size - *pos; + else + no_of_bytes_read = count; + + if (copy_to_user(buf, hdd_ctx->driver_dump_mem + *pos, + no_of_bytes_read)) { + hdd_err("copy to user space failed"); + return -EFAULT; + } + + /* offset(pos) should be updated here based on the copy done */ + *pos += no_of_bytes_read; + + /* Entire driver memory dump copy completed */ + if (*pos >= hdd_ctx->driver_dump_size) + hdd_driver_mem_cleanup(); + + return no_of_bytes_read; +} + + +/** + * struct driver_dump_fops - file operations for driver dump feature + * @read - read function for driver dump operation. + * + * This structure initialize the file operation handle for memory + * dump feature + */ +static const struct file_operations driver_dump_fops = { +read: hdd_driver_memdump_read +}; + +/** + * hdd_driver_memdump_procfs_init() - Initialize procfs for driver memory dump + * + * This function create file under proc file system to be used later for + * processing driver memory dump + * + * Return: 0 on success, error code otherwise. + */ +static int hdd_driver_memdump_procfs_init(void) +{ + hdd_context_t *hdd_ctx; + + hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + if (!hdd_ctx) { + hdd_err("Invalid HDD context"); + return -EINVAL; + } + + proc_dir_driver = proc_mkdir(PROCFS_DRIVER_DUMP_DIR, NULL); + if (proc_dir_driver == NULL) { + pr_debug("Error: Could not initialize /proc/%s\n", + PROCFS_DRIVER_DUMP_DIR); + return -ENOMEM; + } + + proc_file_driver = proc_create_data(PROCFS_DRIVER_DUMP_NAME, + PROCFS_DRIVER_DUMP_PERM, proc_dir_driver, + &driver_dump_fops, hdd_ctx); + if (proc_file_driver == NULL) { + remove_proc_entry(PROCFS_DRIVER_DUMP_NAME, proc_dir_driver); + pr_debug("Error: Could not initialize /proc/%s\n", + PROCFS_DRIVER_DUMP_NAME); + return -ENOMEM; + } + + pr_debug("/proc/%s/%s created\n", PROCFS_DRIVER_DUMP_DIR, + PROCFS_DRIVER_DUMP_NAME); + return 0; +} + +/** + * hdd_driver_memdump_procfs_remove() - Remove file/dir under procfs + * for driver memory dump + * + * This function removes file/dir under proc file system that was + * processing driver memory dump + * + * Return: None + */ +static void hdd_driver_memdump_procfs_remove(void) +{ + remove_proc_entry(PROCFS_DRIVER_DUMP_NAME, proc_dir_driver); + pr_debug("/proc/%s/%s removed\n", PROCFS_DRIVER_DUMP_DIR, + PROCFS_DRIVER_DUMP_NAME); + remove_proc_entry(PROCFS_DRIVER_DUMP_DIR, NULL); + pr_debug("/proc/%s removed\n", PROCFS_DRIVER_DUMP_DIR); +} + +/** + * hdd_driver_memdump_init() - Intialization function for driver + * memory dump feature + * + * This function creates proc file for driver memdump feature + * + * Return - 0 on success, error otherwise + */ +int hdd_driver_memdump_init(void) +{ + int status; + + if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) { + hdd_err("Not initializing memdump in FTM mode"); + return -EINVAL; + } + + status = hdd_driver_memdump_procfs_init(); + if (status) { + hdd_err("Failed to create proc file"); + return status; + } + + return 0; +} + +/** + * hdd_driver_memdump_deinit() - De initialize driver memdump feature + * + * This function removes proc file created for driver memdump feature. + * + * Return: None + */ +void hdd_driver_memdump_deinit(void) +{ + if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) { + hdd_err("Not deinitializing memdump in FTM mode"); + return; + } + + hdd_driver_memdump_procfs_remove(); + + hdd_driver_mem_cleanup(); +} diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c index a1e05650a5c5..2700e9ad55b7 100644 --- a/core/mac/src/pe/lim/lim_api.c +++ b/core/mac/src/pe/lim/lim_api.c @@ -681,6 +681,63 @@ void lim_cleanup(tpAniSirGlobal pMac) } /*** end lim_cleanup() ***/ +/** + * lim_state_info_dump() - print state information of lim layer + * @buf: buffer pointer + * @size: size of buffer to be filled + * + * This function is used to print state information of lim layer + * + * Return: None + */ +static void lim_state_info_dump(char **buf_ptr, uint16_t *size) +{ + tHalHandle hal; + tpAniSirGlobal mac; + uint16_t len = 0; + char *buf = *buf_ptr; + + hal = cds_get_context(QDF_MODULE_ID_PE); + if (hal == NULL) { + QDF_ASSERT(0); + return; + } + + mac = PMAC_STRUCT(hal); + + lim_log(mac, LOG1, FL("size of buffer: %d"), *size); + + len += qdf_scnprintf(buf + len, *size - len, + "\n SmeState: %d", mac->lim.gLimSmeState); + len += qdf_scnprintf(buf + len, *size - len, + "\n PrevSmeState: %d", mac->lim.gLimPrevSmeState); + len += qdf_scnprintf(buf + len, *size - len, + "\n MlmState: %d", mac->lim.gLimMlmState); + len += qdf_scnprintf(buf + len, *size - len, + "\n PrevMlmState: %d", mac->lim.gLimPrevMlmState); + len += qdf_scnprintf(buf + len, *size - len, + "\n SystemInScanLearnMode: %d", + mac->lim.gLimSystemInScanLearnMode); + len += qdf_scnprintf(buf + len, *size - len, + "\n ProcessDefdMsgs: %d", mac->lim.gLimProcessDefdMsgs); + len += qdf_scnprintf(buf + len, *size - len, + "\n gLimHalScanState: %d", mac->lim.gLimHalScanState); + + *size -= len; + *buf_ptr += len; +} + +/** + * lim_register_debug_callback() - registration function for lim layer + * to print lim state information + * + * Return: None + */ +static void lim_register_debug_callback(void) +{ + qdf_register_debug_callback(QDF_MODULE_ID_PE, &lim_state_info_dump); +} + /** ------------------------------------------------------------- \fn pe_open \brief will be called in Open sequence from mac_open @@ -746,6 +803,8 @@ tSirRetStatus pe_open(tpAniSirGlobal pMac, struct cds_config_info *cds_cfg) #ifdef LIM_TRACE_RECORD MTRACE(lim_trace_init(pMac)); #endif + lim_register_debug_callback(); + return status; /* status here will be eSIR_SUCCESS */ pe_open_lock_fail: diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 738ba4302f88..7bfe3c9ff9a4 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -1073,6 +1073,104 @@ bool sme_command_pending(tpAniSirGlobal pMac) LL_ACCESS_NOLOCK); } +/** + * sme_get_sessionid_from_activelist() - gets session id + * @mac: mac context + * + * This function is used to get session id from sme command + * active list + * + * Return: returns session id + */ +uint32_t sme_get_sessionid_from_activelist(tpAniSirGlobal mac) +{ + tListElem *entry; + tSmeCmd *command; + uint32_t session_id = CSR_SESSION_ID_INVALID; + + entry = csr_ll_peek_head(&mac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + if (entry) { + command = GET_BASE_ADDR(entry, tSmeCmd, Link); + session_id = command->sessionId; + } + + return session_id; +} + +/** + * sme_state_info_dump() - prints state information of sme layer + * @buf: buffer pointer + * @size: size of buffer to be filled + * + * This function is used to dump state information of sme layer + * + * Return: None + */ +static void sme_state_info_dump(char **buf_ptr, uint16_t *size) +{ + uint32_t session_id, active_session_id; + tHalHandle hal; + tpAniSirGlobal mac; + uint16_t len = 0; + char *buf = *buf_ptr; + eCsrConnectState connect_state; + + hal = cds_get_context(QDF_MODULE_ID_SME); + if (hal == NULL) { + QDF_ASSERT(0); + return; + } + + mac = PMAC_STRUCT(hal); + sms_log(mac, LOG1, FL("size of buffer: %d"), *size); + + active_session_id = sme_get_sessionid_from_activelist(mac); + if (active_session_id != CSR_SESSION_ID_INVALID) { + len += qdf_scnprintf(buf + len, *size - len, + "\n active command sessionid %d", active_session_id); + } + + for (session_id = 0; session_id < CSR_ROAM_SESSION_MAX; session_id++) { + if (CSR_IS_SESSION_VALID(mac, session_id)) { + connect_state = + mac->roam.roamSession[session_id].connectState; + if ((eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED == + connect_state) + || (eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED == + connect_state)) { + len += qdf_scnprintf(buf + len, *size - len, + "\n NeighborRoamState: %d", + mac->roam.neighborRoamInfo[session_id]. + neighborRoamState); + len += qdf_scnprintf(buf + len, *size - len, + "\n RoamState: %d", mac->roam. + curState[session_id]); + len += qdf_scnprintf(buf + len, *size - len, + "\n RoamSubState: %d", mac->roam. + curSubState[session_id]); + len += qdf_scnprintf(buf + len, *size - len, + "\n ConnectState: %d", + connect_state); + } + } + } + + *size -= len; + *buf_ptr += len; +} + +/** + * sme_register_debug_callback() - registration function sme layer + * to print sme state information + * + * Return: None + */ +static void sme_register_debug_callback(void) +{ + qdf_register_debug_callback(QDF_MODULE_ID_SME, &sme_state_info_dump); +} + + /* Global APIs */ /** @@ -1134,6 +1232,7 @@ QDF_STATUS sme_open(tHalHandle hHal) } sme_p2p_open(pMac); sme_trace_init(pMac); + sme_register_debug_callback(); return status; } diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index ebafc4418589..3b5f543c30ac 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -1673,6 +1673,146 @@ static void wma_init_max_no_of_peers(tp_wma_handle wma_handle, struct wma_version_info g_wmi_version_info; /** + * wma_state_info_dump() - prints state information of wma layer + * @buf: buffer pointer + * @size: size of buffer to be filled + * + * This function is used to dump state information of wma layer + * + * Return: None + */ +static void wma_state_info_dump(char **buf_ptr, uint16_t *size) +{ + tp_wma_handle wma_handle; + uint16_t len = 0; + char *buf = *buf_ptr; + struct wma_txrx_node *iface; + uint8_t vdev_id; + + wma_handle = cds_get_context(QDF_MODULE_ID_WMA); + if (!wma_handle) { + WMA_LOGE("%s: WMA context is invald!", __func__); + return; + } + + WMA_LOGI("%s: size of buffer: %d", __func__, *size); + + len += qdf_scnprintf(buf + len, *size - len, + "\n wow_pno_match_wake_up_count %d", + wma_handle->wow_pno_match_wake_up_count); + len += qdf_scnprintf(buf + len, *size - len, + "\n wow_pno_complete_wake_up_count %d", + wma_handle->wow_pno_complete_wake_up_count); + len += qdf_scnprintf(buf + len, *size - len, + "\n wow_gscan_wake_up_count %d", + wma_handle->wow_gscan_wake_up_count); + len += qdf_scnprintf(buf + len, *size - len, + "\n wow_low_rssi_wake_up_count %d", + wma_handle->wow_low_rssi_wake_up_count); + len += qdf_scnprintf(buf + len, *size - len, + "\n wow_rssi_breach_wake_up_count %d", + wma_handle->wow_rssi_breach_wake_up_count); + len += qdf_scnprintf(buf + len, *size - len, + "\n wow_ucast_wake_up_count %d", + wma_handle->wow_ucast_wake_up_count); + len += qdf_scnprintf(buf + len, *size - len, + "\n wow_bcast_wake_up_count %d", + wma_handle->wow_bcast_wake_up_count); + len += qdf_scnprintf(buf + len, *size - len, + "\n wow_ipv4_mcast_wake_up_count %d", + wma_handle->wow_ipv4_mcast_wake_up_count); + len += qdf_scnprintf(buf + len, *size - len, + "\n wow_ipv6_mcast_ra_stats %d", + wma_handle->wow_ipv6_mcast_ra_stats); + len += qdf_scnprintf(buf + len, *size - len, + "\n wow_ipv6_mcast_ns_stats %d", + wma_handle->wow_ipv6_mcast_ns_stats); + len += qdf_scnprintf(buf + len, *size - len, + "\n wow_ipv6_mcast_na_stats %d", + wma_handle->wow_ipv6_mcast_na_stats); + + for (vdev_id = 0; vdev_id < wma_handle->max_bssid; vdev_id++) { + if (!wma_handle->interfaces[vdev_id].handle) + continue; + + iface = &wma_handle->interfaces[vdev_id]; + + len += qdf_scnprintf(buf + len, *size - len, + "\n vdev_id %d", + vdev_id); + len += qdf_scnprintf(buf + len, *size - len, + "\n conn_state %d", + iface->conn_state); + len += qdf_scnprintf(buf + len, *size - len, + "\n dtimPeriod %d", + iface->dtimPeriod); + len += qdf_scnprintf(buf + len, *size - len, + "\n chanmode %d", + iface->chanmode); + len += qdf_scnprintf(buf + len, *size - len, + "\n vht_capable %d", + iface->vht_capable); + len += qdf_scnprintf(buf + len, *size - len, + "\n ht_capable %d", + iface->ht_capable); + len += qdf_scnprintf(buf + len, *size - len, + "\n chan_width %d", + iface->chan_width); + len += qdf_scnprintf(buf + len, *size - len, + "\n vdev_active %d", + iface->vdev_active); + len += qdf_scnprintf(buf + len, *size - len, + "\n vdev_up %d", + iface->vdev_up); + len += qdf_scnprintf(buf + len, *size - len, + "\n aid %d", + iface->aid); + len += qdf_scnprintf(buf + len, *size - len, + "\n rate_flags %d", + iface->rate_flags); + len += qdf_scnprintf(buf + len, *size - len, + "\n nss %d", + iface->nss); + len += qdf_scnprintf(buf + len, *size - len, + "\n tx_power %d", + iface->tx_power); + len += qdf_scnprintf(buf + len, *size - len, + "\n max_tx_power %d", + iface->max_tx_power); + len += qdf_scnprintf(buf + len, *size - len, + "\n nwType %d", + iface->nwType); + len += qdf_scnprintf(buf + len, *size - len, + "\n tx_streams %d", + iface->tx_streams); + len += qdf_scnprintf(buf + len, *size - len, + "\n rx_streams %d", + iface->rx_streams); + len += qdf_scnprintf(buf + len, *size - len, + "\n chain_mask %d", + iface->chain_mask); + len += qdf_scnprintf(buf + len, *size - len, + "\n nss_2g %d", + iface->nss_2g); + len += qdf_scnprintf(buf + len, *size - len, + "\n nss_5g %d", + iface->nss_5g); + } + + *size -= len; + *buf_ptr += len; +} + +/** + * wma_register_debug_callback() - registration function for wma layer + * to print wma state information + */ +static void wma_register_debug_callback(void) +{ + qdf_register_debug_callback(QDF_MODULE_ID_WMA, &wma_state_info_dump); +} + +/** * wma_open() - Allocate wma context and initialize it. * @cds_context: cds context * @wma_tgt_cfg_cb: tgt config callback fun @@ -2157,6 +2297,8 @@ QDF_STATUS wma_open(void *cds_context, wma_encrypt_decrypt_msg_handler, WMA_RX_SERIALIZER_CTX); wma_ndp_register_all_event_handlers(wma_handle); + wma_register_debug_callback(); + return QDF_STATUS_SUCCESS; err_dbglog_init: |
