From 862541432bb1b8e956492136aacf7b7e3a71b8b6 Mon Sep 17 00:00:00 2001 From: c_cgodav Date: Fri, 17 Feb 2017 12:06:35 +0530 Subject: [PATCH] qcacmn: Add api for dumping the CE discriptors API for dumping the CE descriptors copies all descriptors for the given Copy engine id and also copies the SKB packet pointed by the descriptors till smart_log_skb_sz bytes. Change-Id: I511bda77319944c1ec2377f716087956ce0637ac CRs-Fixed: 2008290 --- dp/inc/cdp_txrx_stats_struct.h | 3 + hif/inc/hif.h | 19 ++++ hif/src/ce/ce_service.c | 198 +++++++++++++++++++++++++++++++++ 3 files changed, 220 insertions(+) diff --git a/dp/inc/cdp_txrx_stats_struct.h b/dp/inc/cdp_txrx_stats_struct.h index 0ab36442ee81..ce32e17faa8e 100644 --- a/dp/inc/cdp_txrx_stats_struct.h +++ b/dp/inc/cdp_txrx_stats_struct.h @@ -1243,8 +1243,11 @@ enum _ol_ath_param_t { OL_ATH_PARAM_DFS_HOST_WAIT_TIMEOUT = 367, #endif OL_ATH_PARAM_NF_THRESH = 368, +#ifdef OL_ATH_SMART_LOGGING OL_ATH_PARAM_SMARTLOG_ENABLE = 369, OL_ATH_PARAM_SMARTLOG_FATAL_EVENT = 370, + OL_ATH_PARAM_SMARTLOG_SKB_SZ = 371, +#endif /* OL_ATH_SMART_LOGGING */ }; diff --git a/hif/inc/hif.h b/hif/inc/hif.h index 47d3418a9584..8c7bdb9411bb 100644 --- a/hif/inc/hif.h +++ b/hif/inc/hif.h @@ -976,4 +976,23 @@ hif_get_ce_service_max_yield_time(struct hif_opaque_softc *hif); */ void hif_set_ce_service_max_rx_ind_flush(struct hif_opaque_softc *hif, uint8_t ce_service_max_rx_ind_flush); +#ifdef OL_ATH_SMART_LOGGING +/* + * hif_log_ce_dump() - Copy all the CE DEST ring to buf + * @scn : HIF handler + * @buf_cur: Current pointer in ring buffer + * @buf_init:Start of the ring buffer + * @buf_sz: Size of the ring buffer + * @ce: Copy Engine id + * @skb_sz: Max size of the SKB buffer to be copied + * + * Calls the respective function to dump all the CE SRC/DEST ring descriptors + * and buffers pointed by them in to the given buf + * + * Return: Current pointer in ring buffer + */ +uint8_t *hif_log_dump_ce(struct hif_softc *scn, uint8_t *buf_cur, + uint8_t *buf_init, uint32_t buf_sz, + uint32_t ce, uint32_t skb_sz); +#endif /* OL_ATH_SMART_LOGGING */ #endif /* _HIF_H_ */ diff --git a/hif/src/ce/ce_service.c b/hif/src/ce/ce_service.c index dade70c83578..5d0e031c3ce6 100644 --- a/hif/src/ce/ce_service.c +++ b/hif/src/ce/ce_service.c @@ -3061,3 +3061,201 @@ ssize_t hif_disp_ce_enable_desc_data_hist(struct hif_softc *scn, char *buf) return len; } #endif /* HIF_CE_DEBUG_DATA_BUF */ + +#ifdef OL_ATH_SMART_LOGGING +#define GUARD_SPACE 10 +#define LOG_ID_SZ 4 +/* + * hif_log_src_ce_dump() - Copy all the CE SRC ring to buf + * @src_ring: SRC ring state + * @buf_cur: Current pointer in ring buffer + * @buf_init:Start of the ring buffer + * @buf_sz: Size of the ring buffer + * @skb_sz: Max size of the SKB buffer to be copied + * + * Dumps all the CE SRC ring descriptors and buffers pointed by them in to + * the given buf, skb_sz is the max buffer size to be copied + * + * Return: Current pointer in ring buffer + */ +static uint8_t *hif_log_src_ce_dump(struct CE_ring_state *src_ring, + uint8_t *buf_cur, uint8_t *buf_init, + uint32_t buf_sz, uint32_t skb_sz) +{ + struct CE_src_desc *src_ring_base; + uint32_t len, entry; + struct CE_src_desc *src_desc; + qdf_nbuf_t nbuf; + uint32_t available_buf; + + src_ring_base = (struct CE_src_desc *)src_ring->base_addr_owner_space; + len = sizeof(struct CE_ring_state); + available_buf = buf_sz - (buf_cur - buf_init); + if (available_buf < (len + GUARD_SPACE)) { + snprintf(buf_cur, available_buf, "END"); + buf_cur = buf_init; + } + + qdf_mem_copy(buf_cur, src_ring, sizeof(struct CE_ring_state)); + buf_cur += sizeof(struct CE_ring_state); + + for (entry = 0; entry < src_ring->nentries; entry++) { + src_desc = CE_SRC_RING_TO_DESC(src_ring_base, entry); + nbuf = src_ring->per_transfer_context[entry]; + if (nbuf) { + uint32_t skb_len = qdf_nbuf_len(nbuf); + uint32_t skb_cp_len = qdf_min(skb_len, skb_sz); + + len = sizeof(struct CE_src_desc) + skb_cp_len + + LOG_ID_SZ + sizeof(skb_cp_len); + available_buf = buf_sz - (buf_cur - buf_init); + if (available_buf < (len + GUARD_SPACE)) { + buf_cur += snprintf(buf_cur, available_buf, + "END"); + buf_cur = buf_init; + } + qdf_mem_copy(buf_cur, src_desc, + sizeof(struct CE_src_desc)); + buf_cur += sizeof(struct CE_src_desc); + + available_buf = buf_sz - (buf_cur - buf_init); + buf_cur += snprintf(buf_cur, available_buf, "SKB%d", + skb_cp_len); + + if (skb_cp_len) { + qdf_mem_copy(buf_cur, qdf_nbuf_data(nbuf), + skb_cp_len); + buf_cur += skb_cp_len; + } + } else { + len = sizeof(struct CE_src_desc) + LOG_ID_SZ; + available_buf = buf_sz - (buf_cur - buf_init); + if (available_buf < (len + GUARD_SPACE)) { + buf_cur += snprintf(buf_cur, available_buf, + "END"); + buf_cur = buf_init; + } + qdf_mem_copy(buf_cur, src_desc, + sizeof(struct CE_src_desc)); + buf_cur += sizeof(struct CE_src_desc); + available_buf = buf_sz - (buf_cur - buf_init); + buf_cur += snprintf(buf_cur, available_buf, "NUL"); + } + } + + return buf_cur; +} + +/* + * hif_log_dest_ce_dump() - Copy all the CE DEST ring to buf + * @dest_ring: SRC ring state + * @buf_cur: Current pointer in ring buffer + * @buf_init:Start of the ring buffer + * @buf_sz: Size of the ring buffer + * @skb_sz: Max size of the SKB buffer to be copied + * + * Dumps all the CE SRC ring descriptors and buffers pointed by them in to + * the given buf, skb_sz is the max buffer size to be copied + * + * Return: Current pointer in ring buffer + */ +static uint8_t *hif_log_dest_ce_dump(struct CE_ring_state *dest_ring, + uint8_t *buf_cur, uint8_t *buf_init, + uint32_t buf_sz, uint32_t skb_sz) +{ + struct CE_dest_desc *dest_ring_base; + uint32_t len, entry; + struct CE_dest_desc *dest_desc; + qdf_nbuf_t nbuf; + uint32_t available_buf; + + dest_ring_base = + (struct CE_dest_desc *)dest_ring->base_addr_owner_space; + + len = sizeof(struct CE_ring_state); + available_buf = buf_sz - (buf_cur - buf_init); + if (available_buf < (len + GUARD_SPACE)) { + snprintf(buf_cur, available_buf, "END"); + buf_cur = buf_init; + } + + qdf_mem_copy(buf_cur, dest_ring, sizeof(struct CE_ring_state)); + buf_cur += sizeof(struct CE_ring_state); + + for (entry = 0; entry < dest_ring->nentries; entry++) { + dest_desc = CE_DEST_RING_TO_DESC(dest_ring_base, entry); + nbuf = dest_ring->per_transfer_context[entry]; + if (nbuf) { + uint32_t skb_len = qdf_nbuf_len(nbuf); + uint32_t skb_cp_len = qdf_min(skb_len, skb_sz); + + len = sizeof(struct CE_dest_desc) + skb_cp_len + + LOG_ID_SZ + sizeof(skb_cp_len); + + available_buf = buf_sz - (buf_cur - buf_init); + if (available_buf < (len + GUARD_SPACE)) { + buf_cur += snprintf(buf_cur, available_buf, + "END"); + buf_cur = buf_init; + } + + qdf_mem_copy(buf_cur, dest_desc, + sizeof(struct CE_dest_desc)); + buf_cur += sizeof(struct CE_dest_desc); + available_buf = buf_sz - (buf_cur - buf_init); + buf_cur += snprintf(buf_cur, available_buf, "SKB%d", + skb_cp_len); + if (skb_cp_len) { + qdf_mem_copy(buf_cur, qdf_nbuf_data(nbuf), + skb_cp_len); + buf_cur += skb_cp_len; + } + } else { + len = sizeof(struct CE_dest_desc) + LOG_ID_SZ; + available_buf = buf_sz - (buf_cur - buf_init); + if (available_buf < (len + GUARD_SPACE)) { + buf_cur += snprintf(buf_cur, available_buf, + "END"); + buf_cur = buf_init; + } + qdf_mem_copy(buf_cur, dest_desc, + sizeof(struct CE_dest_desc)); + buf_cur += sizeof(struct CE_dest_desc); + available_buf = buf_sz - (buf_cur - buf_init); + buf_cur += snprintf(buf_cur, available_buf, "NUL"); + } + } + return buf_cur; +} + +/** + * hif_log_ce_dump() - Copy all the CE DEST ring to buf + * Calls the respective function to dump all the CE SRC/DEST ring descriptors + * and buffers pointed by them in to the given buf + */ +uint8_t *hif_log_dump_ce(struct hif_softc *scn, uint8_t *buf_cur, + uint8_t *buf_init, uint32_t buf_sz, + uint32_t ce, uint32_t skb_sz) +{ + struct CE_state *ce_state; + struct CE_ring_state *src_ring; + struct CE_ring_state *dest_ring; + + ce_state = scn->ce_id_to_state[ce]; + src_ring = ce_state->src_ring; + dest_ring = ce_state->dest_ring; + + if (src_ring) { + buf_cur = hif_log_src_ce_dump(src_ring, buf_cur, + buf_init, buf_sz, skb_sz); + } else if (dest_ring) { + buf_cur = hif_log_dest_ce_dump(dest_ring, buf_cur, + buf_init, buf_sz, skb_sz); + } else { + qdf_print("Cannot print Ring for Unused CE%d\n", ce); + } + + return buf_cur; +} +#endif /* OL_ATH_SMART_LOGGING */ +