summaryrefslogtreecommitdiff
path: root/CORE/SVC/src
diff options
context:
space:
mode:
authorPadma, Santhosh Kumar <skpadma@qti.qualcomm.com>2016-01-08 17:18:14 +0530
committerAnjaneedevi Kapparapu <akappa@codeaurora.org>2016-02-12 17:15:54 +0530
commitd2a8c59cd298d42b629e1493c8f36b4c635aa85e (patch)
treeeed4bf5d719bf5e77d5a1f2946fe1e390ca7fcb2 /CORE/SVC/src
parentb02f81796a30a6922f256b3276fb3d709b0dc47b (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.c289
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 */