diff options
| author | Padma, Santhosh Kumar <skpadma@qti.qualcomm.com> | 2016-01-08 17:18:14 +0530 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2016-02-12 17:15:54 +0530 |
| commit | d2a8c59cd298d42b629e1493c8f36b4c635aa85e (patch) | |
| tree | eed4bf5d719bf5e77d5a1f2946fe1e390ca7fcb2 /CORE/SVC/src | |
| parent | b02f81796a30a6922f256b3276fb3d709b0dc47b (diff) | |
qcacld-2.0: Dump Tx/Rx packets during connection
Add changes to send 32 tx/rx packets to HAL layer during connection.
This can help in debugging connection related issues.
Change-Id: Icd08475c3f81aa182c902b8e8defbdb904c5509d
CRs-Fixed: 959645
Diffstat (limited to 'CORE/SVC/src')
| -rw-r--r-- | CORE/SVC/src/logging/wlan_logging_sock_svc.c | 289 |
1 files changed, 276 insertions, 13 deletions
diff --git a/CORE/SVC/src/logging/wlan_logging_sock_svc.c b/CORE/SVC/src/logging/wlan_logging_sock_svc.c index 729ddfd65ca9..add8ed5d0821 100644 --- a/CORE/SVC/src/logging/wlan_logging_sock_svc.c +++ b/CORE/SVC/src/logging/wlan_logging_sock_svc.c @@ -44,6 +44,35 @@ #include "pktlog_ac.h" #include <linux/rtc.h> #include <vos_diag_core_log.h> +#include "limApi.h" +#include "ol_txrx_api.h" +#include "csrApi.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, +}; + +static uint8_t gtx_count; +static uint8_t grx_count; + #define LOGGING_TRACE(level, args...) \ VOS_TRACE(VOS_MODULE_ID_HDD, level, ## args) @@ -79,13 +108,15 @@ struct log_msg { * Tx/Rx packet stats * @status: Status * @type: Type - * @reserved: Reserved + * @driver_ts: driver timestamp + * @fw_ts: fw timestamp */ struct packet_dump { unsigned char status; unsigned char type; - unsigned char reserved[6]; + uint32_t driver_ts; + uint16_t fw_ts; }; /** @@ -450,7 +481,8 @@ static int pkt_stats_fill_headers(struct sk_buff *skb) diag_type = DIAG_TYPE_LOGS; vos_mem_copy(skb_push(skb, sizeof(int)), &diag_type, sizeof(int)); - extra_header_len = sizeof(msg_header.radio) + sizeof(tAniHdr); + extra_header_len = sizeof(msg_header.radio) + sizeof(tAniHdr) + + sizeof(struct nlmsghdr); nl_payload_len = NLMSG_ALIGN(extra_header_len + skb->len); msg_header.nlh.nlmsg_type = ANI_NL_MSG_PUMAC; @@ -1119,12 +1151,7 @@ void wlan_pkt_stats_to_logger_thread(void *pl_hdr, void *pkt_dump, void *data) } pkt_stats_dump = (struct packet_dump *)pkt_dump; - if (pkt_stats_dump) - total_stats_len = sizeof(struct ath_pktlog_hdr) + - pktlog_hdr->size + - sizeof(struct packet_dump); - else - total_stats_len = sizeof(struct ath_pktlog_hdr) + + total_stats_len = sizeof(struct ath_pktlog_hdr) + pktlog_hdr->size; spin_lock_irqsave(&gwlan_logging.pkt_stats_lock, flags); @@ -1149,15 +1176,18 @@ void wlan_pkt_stats_to_logger_thread(void *pl_hdr, void *pkt_dump, void *data) pktlog_hdr, sizeof(struct ath_pktlog_hdr)); - if (pkt_stats_dump) + if (pkt_stats_dump) { vos_mem_copy(skb_put(ptr, sizeof(struct packet_dump)), pkt_stats_dump, sizeof(struct packet_dump)); + pktlog_hdr->size -= sizeof(struct packet_dump); + } - vos_mem_copy(skb_put(ptr, - pktlog_hdr->size), - data, pktlog_hdr->size); + if (data) + vos_mem_copy(skb_put(ptr, + pktlog_hdr->size), + data, pktlog_hdr->size); spin_unlock_irqrestore(&gwlan_logging.pkt_stats_lock, flags); @@ -1168,4 +1198,237 @@ void wlan_pkt_stats_to_logger_thread(void *pl_hdr, void *pkt_dump, void *data) } } +/** + * 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(adf_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 = vos_get_global_context(VOS_MODULE_ID_HDD, NULL); + if (!vos_ctx) + return; + + hdd_ctx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_ctx); + if (!hdd_ctx) + return; + + adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id); + + /* Send packet dump only for STA interface */ + if (adapter->device_mode != WLAN_HDD_INFRA_STATION) + return; + + pktlog_hdr.log_type = PKTLOG_TYPE_PKT_DUMP; + pktlog_hdr.size = sizeof(pd_hdr) + adf_nbuf_len(netbuf); + + pd_hdr.status = status; + pd_hdr.type = type; + pd_hdr.driver_ts = vos_timer_get_system_time(); + + 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}; + + pktlog_hdr.log_type = PKTLOG_TYPE_PKT_DUMP; + pktlog_hdr.size = sizeof(pd_hdr); + + pd_hdr.type = type; + + LOGGING_TRACE(VOS_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(); + pe_deregister_packetdump_callback(); + htt_deregister_packetdump_callback(); + send_packetdump_monitor(STOP_MONITOR); + csr_packetdump_timer_stop(); + + gtx_count = 0; + grx_count = 0; + } else + LOGGING_TRACE(VOS_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(VOS_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(adf_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(adf_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); + pe_register_packetdump_callback(rx_packetdump_cb); + htt_register_packetdump_callback(rx_packetdump_cb); + send_packetdump_monitor(START_MONITOR); + + gtx_count = 0; + grx_count = 0; +} #endif /* WLAN_LOGGING_SOCK_SVC_ENABLE */ |
