summaryrefslogtreecommitdiff
path: root/core/utils
diff options
context:
space:
mode:
authorHimanshu Agarwal <himanaga@codeaurora.org>2016-12-05 17:21:12 +0530
committerqcabuildsw <qcabuildsw@localhost>2016-12-09 13:22:33 -0800
commit3ed01151ef6ca83ea5745baffeb214e21f2f46c3 (patch)
tree553e24ff07f89c170bca0d6d11efe5793cbb670f /core/utils
parent73bc5c2c99d8f33c4fd1520eb80e6c92b9d9f7ab (diff)
Revert "Revert "qcacld-3.0: Dump Tx/Rx packets during connection""
This reverts Change-Id I2aec7253511d2ca7b08ca77d858a46f9c01d4e9d Adding support for dumping 32 tx/rx packets during connection by reverting above change as "exceeding skb buffer size and leading to crash" issue is resolved with this change. Change-Id: I951355776461706bb52eeee0527819377e7b7857 CRs-Fixed: 1097280
Diffstat (limited to 'core/utils')
-rw-r--r--core/utils/logging/inc/wlan_logging_sock_svc.h3
-rw-r--r--core/utils/logging/src/wlan_logging_sock_svc.c286
2 files changed, 280 insertions, 9 deletions
diff --git a/core/utils/logging/inc/wlan_logging_sock_svc.h b/core/utils/logging/inc/wlan_logging_sock_svc.h
index 1edb42cea675..af85ab694352 100644
--- a/core/utils/logging/inc/wlan_logging_sock_svc.h
+++ b/core/utils/logging/inc/wlan_logging_sock_svc.h
@@ -80,4 +80,7 @@ static inline void wlan_report_log_completion(uint32_t is_fatal,
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/core/utils/logging/src/wlan_logging_sock_svc.c b/core/utils/logging/src/wlan_logging_sock_svc.c
index 3661674befb1..ab8950cd9f69 100644
--- a/core/utils/logging/src/wlan_logging_sock_svc.c
+++ b/core/utils/logging/src/wlan_logging_sock_svc.c
@@ -37,10 +37,39 @@
#include <kthread.h>
#include <qdf_time.h>
#include <wlan_ptt_sock_svc.h>
-#include "pktlog_ac.h"
#include <host_diag_core_event.h>
#include "cds_utils.h"
#include "host_diag_core_log.h"
+#include "wma.h"
+#include "ol_txrx_api.h"
+#include "csr_api.h"
+#include "wlan_hdd_main.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,
+};
+
+static uint8_t gtx_count;
+static uint8_t grx_count;
#define LOGGING_TRACE(level, args ...) \
QDF_TRACE(QDF_MODULE_ID_HDD, level, ## args)
@@ -1200,12 +1229,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);
@@ -1230,16 +1254,24 @@ 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) {
qdf_mem_copy(skb_put(ptr,
sizeof(struct packet_dump)),
pkt_stats_dump,
sizeof(struct packet_dump));
+ pktlog_hdr->size -= sizeof(struct packet_dump);
+ }
- qdf_mem_copy(skb_put(ptr,
+ 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 */
@@ -1249,4 +1281,240 @@ 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(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;
+
+ 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};
+
+ 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 /* WLAN_LOGGING_SOCK_SVC_ENABLE */