diff --git a/qdf/inc/qdf_trace.h b/qdf/inc/qdf_trace.h index b0f74321f5..d992ee54dc 100644 --- a/qdf/inc/qdf_trace.h +++ b/qdf/inc/qdf_trace.h @@ -75,8 +75,10 @@ typedef int (qdf_abstract_print)(void *priv, const char *fmt, ...); /* DP Trace Implementation */ #ifdef CONFIG_DP_TRACE #define DPTRACE(p) p +#define DPTRACE_PRINT(args...) QDF_TRACE_DEBUG(QDF_MODULE_ID_QDF, args) #else #define DPTRACE(p) +#define DPTRACE_PRINT(args...) #endif /* By default Data Path module will have all log levels enabled, except debug @@ -161,8 +163,8 @@ typedef struct s_qdf_trace_data { #define CASE_RETURN_STRING(str) case ((str)): return (uint8_t *)(# str); -#define MAX_QDF_DP_TRACE_RECORDS 4000 -#define QDF_DP_TRACE_RECORD_SIZE 16 +#define MAX_QDF_DP_TRACE_RECORDS 2000 +#define QDF_DP_TRACE_RECORD_SIZE 40 #define INVALID_QDF_DP_TRACE_ADDR 0xffffffff #define QDF_DP_TRACE_VERBOSITY_HIGH 3 #define QDF_DP_TRACE_VERBOSITY_MEDIUM 2 @@ -177,13 +179,14 @@ typedef struct s_qdf_trace_data { * @QDF_DP_TRACE_DHCP_PACKET_RECORD - record DHCP packet * @QDF_DP_TRACE_ARP_PACKET_RECORD - record ARP packet * @QDF_DP_TRACE_MGMT_PACKET_RECORD - record MGMT pacekt - * @QDF_DP_TRACE_ICMP_PACKET_RECORD - record ICMP packet - * @QDF_DP_TRACE_ICMPv6_PACKET_RECORD - record ICMPv6 packet * QDF_DP_TRACE_EVENT_RECORD - record events * @QDF_DP_TRACE_BASE_VERBOSITY - below this are part of base verbosity - * @QDF_DP_TRACE_ICMP_PACKET_RECORD - record ICMP packets + * @QDF_DP_TRACE_ICMP_PACKET_RECORD - record ICMP packet + * @QDF_DP_TRACE_ICMPv6_PACKET_RECORD - record ICMPv6 packet * @QDF_DP_TRACE_HDD_TX_PACKET_RECORD - record 32 bytes of tx pkt at HDD * @QDF_DP_TRACE_HDD_RX_PACKET_RECORD - record 32 bytes of rx pkt at HDD + * @QDF_DP_TRACE_TX_PACKET_RECORD - record 32 bytes of tx pkt at any layer + * @QDF_DP_TRACE_RX_PACKET_RECORD - record 32 bytes of rx pkt at any layer * @QDF_DP_TRACE_HDD_TX_TIMEOUT - HDD tx timeout * @QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT- SOFTAP HDD tx timeout * @QDF_DP_TRACE_FREE_PACKET_PTR_RECORD - tx completion ptr record @@ -224,6 +227,8 @@ enum QDF_DP_TRACE_ID { QDF_DP_TRACE_ICMPv6_PACKET_RECORD, QDF_DP_TRACE_HDD_TX_PACKET_RECORD, QDF_DP_TRACE_HDD_RX_PACKET_RECORD, + QDF_DP_TRACE_TX_PACKET_RECORD, + QDF_DP_TRACE_RX_PACKET_RECORD, QDF_DP_TRACE_HDD_TX_TIMEOUT, QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT, QDF_DP_TRACE_FREE_PACKET_PTR_RECORD, @@ -318,6 +323,14 @@ struct qdf_dp_trace_event_buf { uint8_t subtype; }; +/** + * struct qdf_dp_trace_data_buf - nbuf data buffer + * @msdu_id : msdu id + */ +struct qdf_dp_trace_data_buf { + uint16_t msdu_id; +}; + /** * struct qdf_dp_trace_record_s - Describes a record in DP trace * @time: time when it got stored @@ -327,7 +340,7 @@ struct qdf_dp_trace_event_buf { * @pid : process id which stored the data in this record */ struct qdf_dp_trace_record_s { - char time[20]; + uint64_t time; uint8_t code; uint8_t data[QDF_DP_TRACE_RECORD_SIZE]; uint8_t size; @@ -346,7 +359,11 @@ struct qdf_dp_trace_record_s { * @enable: enable/disable DP trace * @count: current packet number * @live_mode_config: configuration as received during initialization - * @live_mode: current live mode, enabled or disabled. + * @live_mode: current live mode, enabled or disabled, can be throttled based + * on throughput + * @force_live_mode: flag to enable live mode all the time for all packets. + * This can be set/unset from userspace and overrides other + * live mode flags. * @print_pkt_cnt: count of number of packets printed in live mode * @high_tput_thresh: thresh beyond which live mode is turned off * @thresh_time_limit: max time, in terms of BW timer intervals to wait, @@ -385,6 +402,7 @@ struct s_qdf_dp_trace_data { bool live_mode; uint32_t curr_pos; uint32_t saved_tail; + bool force_live_mode; uint8_t print_pkt_cnt; uint8_t high_tput_thresh; uint16_t thresh_time_limit; @@ -512,6 +530,9 @@ QDF_STATUS qdf_trace_spin_lock_init(void) void qdf_dp_set_proto_bitmap(uint32_t val); void qdf_dp_trace_set_verbosity(uint32_t val); void qdf_dp_set_no_of_record(uint32_t val); +#define QDF_DP_TRACE_RECORD_INFO_LIVE (0x1) +#define QDF_DP_TRACE_RECORD_INFO_THROTTLED (0x1 << 1) + bool qdf_dp_trace_log_pkt(uint8_t session_id, struct sk_buff *skb, enum qdf_proto_dir dir, uint8_t pdev_id); void qdf_dp_trace_init(bool live_mode_config, uint8_t thresh, @@ -562,38 +583,146 @@ void qdf_dpt_set_value_debugfs(uint8_t proto_bitmap, uint8_t no_of_record, */ void qdf_dp_trace_dump_stats(void); typedef void (*tp_qdf_dp_trace_cb)(struct qdf_dp_trace_record_s*, - uint16_t, uint8_t, bool live); + uint16_t, uint8_t, uint8_t info); +/** + * qdf_dp_display_record() - Displays a record in DP trace + * @record: pointer to a record in DP trace + * @index: record index + * @pdev_id: pdev id for the mgmt pkt + * @info: info used to display pkt (live mode, throttling) + * + * Return: None + */ void qdf_dp_display_record(struct qdf_dp_trace_record_s *record, - uint16_t index, uint8_t pdev_id, bool live); -void qdf_dp_trace_ptr(qdf_nbuf_t nbuf, enum QDF_DP_TRACE_ID code, - uint8_t pdev_id, uint8_t *data, uint8_t size, uint16_t msdu_id, - uint16_t status); -void qdf_dp_trace_throttle_live_mode(bool high_bw_request); -void qdf_dp_display_ptr_record(struct qdf_dp_trace_record_s *pRecord, - uint16_t recIndex, uint8_t pdev_id, bool live); + uint16_t index, uint8_t pdev_id, + uint8_t info); + +/** + * qdf_dp_display_ptr_record() - display record + * @record: dptrace record + * @rec_index: index + * @pdev_id: pdev id for the mgmt pkt + * @info: info used to display pkt (live mode, throttling) + * + * Return: none + */ +void qdf_dp_display_ptr_record(struct qdf_dp_trace_record_s *record, + uint16_t rec_index, uint8_t pdev_id, + uint8_t info); + +/** + * qdf_dp_display_proto_pkt() - display proto packet + * @record: dptrace record + * @index: index + * @pdev_id: pdev id for the mgmt pkt + * @info: info used to display pkt (live mode, throttling) + * + * Return: none + */ void qdf_dp_display_proto_pkt(struct qdf_dp_trace_record_s *record, - uint16_t index, uint8_t pdev_id, bool live); + uint16_t index, uint8_t pdev_id, + uint8_t info); +/** + * qdf_dp_display_data_pkt_record() - Displays a data packet in DP trace + * @record: pointer to a record in DP trace + * @rec_index: record index + * @pdev_id: pdev id + * @info: display info regarding record + * + * Return: None + */ +void +qdf_dp_display_data_pkt_record(struct qdf_dp_trace_record_s *record, + uint16_t rec_index, uint8_t pdev_id, + uint8_t info); + +void qdf_dp_trace_ptr(qdf_nbuf_t nbuf, enum QDF_DP_TRACE_ID code, + uint8_t pdev_id, uint8_t *data, uint8_t size, + uint16_t msdu_id, uint16_t status); +void qdf_dp_trace_throttle_live_mode(bool high_bw_request); + +/** + * qdf_dp_trace_data_pkt() - trace data packet + * @nbuf: nbuf which needs to be traced + * @pdev_id: pdev_id + * @code: QDF_DP_TRACE_ID for the packet (TX or RX) + * @msdu_id: tx desc id for the nbuf (Only applies to TX packets) + * @dir: TX or RX packet direction + * + * Return: None + */ +void qdf_dp_trace_data_pkt(qdf_nbuf_t nbuf, uint8_t pdev_id, + enum QDF_DP_TRACE_ID code, uint16_t msdu_id, + enum qdf_proto_dir dir); + uint8_t qdf_dp_get_proto_bitmap(void); uint8_t qdf_dp_get_verbosity(void); uint8_t qdf_dp_get_no_of_record(void); + +/** + * qdf_dp_trace_proto_pkt() - record proto packet + * @code: dptrace code + * @vdev_id: vdev id + * @sa: source mac address + * @da: destination mac address + * @type: proto type + * @subtype: proto subtype + * @dir: direction + * @pdev_id: pdev id + * @print: to print this proto pkt or not + * + * Return: none + */ void qdf_dp_trace_proto_pkt(enum QDF_DP_TRACE_ID code, uint8_t vdev_id, uint8_t *sa, uint8_t *da, enum qdf_proto_type type, enum qdf_proto_subtype subtype, enum qdf_proto_dir dir, uint8_t pdev_id, bool print); + void qdf_dp_trace_disable_live_mode(void); void qdf_dp_trace_enable_live_mode(void); void qdf_dp_trace_clear_buffer(void); +/** + * qdf_dp_trace_mgmt_pkt() - record mgmt packet + * @code: dptrace code + * @vdev_id: vdev id + * @pdev_id: pdev_id + * @type: proto type + * @subtype: proto subtype + * + * Return: none + */ void qdf_dp_trace_mgmt_pkt(enum QDF_DP_TRACE_ID code, uint8_t vdev_id, - uint8_t pdev_id, enum qdf_proto_type type, - enum qdf_proto_subtype subtype); + uint8_t pdev_id, enum qdf_proto_type type, + enum qdf_proto_subtype subtype); + +/** + * qdf_dp_display_mgmt_pkt() - display proto packet + * @record: dptrace record + * @index: index + * @pdev_id: pdev id for the mgmt pkt + * @info: info used to display pkt (live mode, throttling) + * + * Return: none + */ void qdf_dp_display_mgmt_pkt(struct qdf_dp_trace_record_s *record, - uint16_t index, uint8_t pdev_id, bool live); + uint16_t index, uint8_t pdev_id, uint8_t info); + +/** + * qdf_dp_display_event_record() - display event records + * @record: dptrace record + * @index: index + * @pdev_id: pdev id for the mgmt pkt + * @info: info used to display pkt (live mode, throttling) + * + * Return: none + */ void qdf_dp_display_event_record(struct qdf_dp_trace_record_s *record, - uint16_t index, uint8_t pdev_id, bool live); + uint16_t index, uint8_t pdev_id, uint8_t info); + void qdf_dp_trace_record_event(enum QDF_DP_TRACE_ID code, uint8_t vdev_id, - uint8_t pdev_id, enum qdf_proto_type type, - enum qdf_proto_subtype subtype); + uint8_t pdev_id, enum qdf_proto_type type, + enum qdf_proto_subtype subtype); #else static inline bool qdf_dp_trace_log_pkt(uint8_t session_id, struct sk_buff *skb, @@ -664,10 +793,13 @@ void qdf_dp_trace_clear_buffer(void) { } +void qdf_dp_trace_data_pkt(qdf_nbuf_t nbuf, uint8_t pdev_id, + enum QDF_DP_TRACE_ID code, uint16_t msdu_id, + enum qdf_proto_dir dir) +{ +} #endif - - void qdf_trace_display(void); void qdf_trace_set_value(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, diff --git a/qdf/linux/src/qdf_nbuf.c b/qdf/linux/src/qdf_nbuf.c index f89087826f..77618ce460 100644 --- a/qdf/linux/src/qdf_nbuf.c +++ b/qdf/linux/src/qdf_nbuf.c @@ -1219,9 +1219,6 @@ __qdf_nbuf_data_get_icmp_subtype(uint8_t *data) subtype = (uint8_t)(*(uint8_t *) (data + ICMP_SUBTYPE_OFFSET)); - QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG, - "ICMP proto type: 0x%02x", subtype); - switch (subtype) { case ICMP_REQUEST: proto_subtype = QDF_PROTO_ICMP_REQ; @@ -1254,9 +1251,6 @@ __qdf_nbuf_data_get_icmpv6_subtype(uint8_t *data) subtype = (uint8_t)(*(uint8_t *) (data + ICMPV6_SUBTYPE_OFFSET)); - QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG, - "ICMPv6 proto type: 0x%02x", subtype); - switch (subtype) { case ICMPV6_REQUEST: proto_subtype = QDF_PROTO_ICMPV6_REQ; diff --git a/qdf/linux/src/qdf_trace.c b/qdf/linux/src/qdf_trace.c index ccc35c4456..a4e7f87c12 100644 --- a/qdf/linux/src/qdf_trace.c +++ b/qdf/linux/src/qdf_trace.c @@ -67,6 +67,8 @@ typedef struct { unsigned char module_name_str[4]; } module_trace_info; +#define DP_TRACE_META_DATA_STRLEN 50 + /* Array of static data that contains all of the per module trace * information. This includes the trace level for the module and * the 3 character 'name' of the module for marking the trace logs @@ -333,7 +335,7 @@ qdf_export_symbol(qdf_vtrace_msg); #define ROW_SIZE 16 /* Buffer size = data bytes(2 hex chars plus space) + NULL */ -#define BUFFER_SIZE ((ROW_SIZE * 3) + 1) +#define BUFFER_SIZE ((QDF_DP_TRACE_RECORD_SIZE * 3) + 1) /** * qdf_trace_hex_dump() - externally called hex dump function @@ -735,8 +737,9 @@ QDF_STATUS qdf_state_info_dump_all(char *buf, uint16_t size, qdf_export_symbol(qdf_state_info_dump_all); #ifdef CONFIG_DP_TRACE +#define QDF_DP_TRACE_PREPEND_STR_SIZE 100 static void qdf_dp_unused(struct qdf_dp_trace_record_s *record, - uint16_t index, uint8_t pdev_id, bool live) + uint16_t index, uint8_t pdev_id, uint8_t info) { qdf_print("%s: QDF_DP_TRACE_MAX event should not be generated", __func__); @@ -781,6 +784,13 @@ void qdf_dp_trace_init(bool live_mode_config, uint8_t thresh, for (i = 0; i < ARRAY_SIZE(qdf_dp_trace_cb_table); i++) qdf_dp_trace_cb_table[i] = qdf_dp_display_record; + qdf_dp_trace_cb_table[QDF_DP_TRACE_HDD_TX_PACKET_RECORD] = + qdf_dp_trace_cb_table[QDF_DP_TRACE_HDD_RX_PACKET_RECORD] = + qdf_dp_trace_cb_table[QDF_DP_TRACE_TX_PACKET_RECORD] = + qdf_dp_trace_cb_table[QDF_DP_TRACE_RX_PACKET_RECORD] = + qdf_dp_trace_cb_table[QDF_DP_TRACE_DROP_PACKET_RECORD] = + qdf_dp_display_data_pkt_record; + qdf_dp_trace_cb_table[QDF_DP_TRACE_TXRX_PACKET_PTR_RECORD] = qdf_dp_trace_cb_table[QDF_DP_TRACE_TXRX_FAST_PACKET_PTR_RECORD] = qdf_dp_trace_cb_table[QDF_DP_TRACE_FREE_PACKET_PTR_RECORD] = @@ -957,33 +967,42 @@ void qdf_dp_trace_set_track(qdf_nbuf_t nbuf, enum qdf_proto_dir dir) } qdf_export_symbol(qdf_dp_trace_set_track); -#define DPTRACE_PRINT(args...) \ - QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG, ## args) +/* Number of bytes to be grouped together while printing DP-Trace data */ +#define QDF_DUMP_DP_GROUP_SIZE 6 /** - * dump_hex_trace() - Display the data in buffer - * @str: string to prepend the hexdump with. - * @buf: buffer which contains data to be displayed - * @buf_len: defines the size of the data to be displayed + * dump_dp_hex_trace() - Display the data in buffer + * @prepend_str: string to prepend the hexdump with. + * @inbuf: buffer which contains data to be displayed + * @inbuf_len: defines the size of the data to be displayed * * Return: None */ -static void dump_dp_hex_trace(char *str, uint8_t *buf, uint8_t buf_len) +static void +dump_dp_hex_trace(char *prepend_str, uint8_t *inbuf, uint8_t inbuf_len) { - unsigned char linebuf[BUFFER_SIZE]; - const u8 *ptr = buf; - int i, linelen, remaining = buf_len; + unsigned char outbuf[BUFFER_SIZE]; + const uint8_t *inbuf_ptr = inbuf; + char *outbuf_ptr = outbuf; + int outbytes_written = 0; - /* Dump the bytes in the last line */ - for (i = 0; i < buf_len; i += ROW_SIZE) { - linelen = min(remaining, ROW_SIZE); - remaining -= ROW_SIZE; + qdf_mem_set(outbuf, 0, sizeof(outbuf)); + do { + outbytes_written += scnprintf(outbuf_ptr, + BUFFER_SIZE - outbytes_written, + "%02x", *inbuf_ptr); + outbuf_ptr = outbuf + outbytes_written; - hex_dump_to_buffer(ptr + i, linelen, ROW_SIZE, 1, - linebuf, sizeof(linebuf), false); - - DPTRACE_PRINT("DPT: %s %s", str, linebuf); - } + if ((inbuf_ptr - inbuf) && + (inbuf_ptr - inbuf + 1) % QDF_DUMP_DP_GROUP_SIZE == 0) { + outbytes_written += scnprintf(outbuf_ptr, + BUFFER_SIZE - outbytes_written, + " "); + outbuf_ptr = outbuf + outbytes_written; + } + inbuf_ptr++; + } while (inbuf_ptr < (inbuf + inbuf_len)); + DPTRACE_PRINT("%s %s", prepend_str, outbuf); } /** @@ -1020,6 +1039,8 @@ const char *qdf_dp_code_to_string(enum QDF_DP_TRACE_ID code) return "HDD: TX: DATA:"; case QDF_DP_TRACE_LI_DP_TX_PACKET_RECORD: return "LI_DP: TX: DATA:"; + case QDF_DP_TRACE_TX_PACKET_RECORD: + return "TX:"; case QDF_DP_TRACE_CE_PACKET_PTR_RECORD: return "CE: TX: PTR:"; case QDF_DP_TRACE_CE_FAST_PACKET_PTR_RECORD: @@ -1042,6 +1063,8 @@ const char *qdf_dp_code_to_string(enum QDF_DP_TRACE_ID code) return "LI_DP: RX: DATA:"; case QDF_DP_TRACE_LI_DP_NULL_RX_PACKET_RECORD: return "LI_DP_NULL: RX: DATA:"; + case QDF_DP_TRACE_RX_PACKET_RECORD: + return "RX:"; case QDF_DP_TRACE_TXRX_QUEUE_PACKET_PTR_RECORD: return "TXRX: TX: Q: PTR:"; case QDF_DP_TRACE_TXRX_PACKET_PTR_RECORD: @@ -1206,20 +1229,117 @@ static bool qdf_dp_enable_check(qdf_nbuf_t nbuf, enum QDF_DP_TRACE_ID code, } /** - * qdf_dp_add_record() - add dp trace record - * @code: dptrace code - * @data: data pointer - * @size: size of buffer - * @pdev_id: pdev_id - * @print: true to print it in kmsg + * qdf_dp_trace_fill_meta_str() - fill up a common meta string + * @prepend_str: pointer to string + * @size: size of prepend_str + * @rec_index: index of record + * @info: info related to the record + * @record: pointer to the record + * + * Return: ret value from scnprintf + */ +static inline +int qdf_dp_trace_fill_meta_str(char *prepend_str, int size, + int rec_index, uint8_t info, + struct qdf_dp_trace_record_s *record) +{ + char buffer[20]; + int ret = 0; + bool live = info & QDF_DP_TRACE_RECORD_INFO_LIVE ? true : false; + bool throttled = info & QDF_DP_TRACE_RECORD_INFO_THROTTLED ? + true : false; + + scnprintf(buffer, sizeof(buffer), "%llu", record->time); + ret = scnprintf(prepend_str, size, + "%s DPT: %04d:%02d%s %s", + throttled ? "*" : "", + rec_index, + record->pdev_id, + live ? "" : buffer, + qdf_dp_code_to_string(record->code)); + + return ret; +} + +/** + * qdf_dp_fill_record_data() - fill meta data and data into the record + * @rec: pointer to record data + * @data: pointer to data + * @data_size: size of the data + * @meta_data: pointer to metadata + * @metadata_size: size of metadata + * + * Should be called from within a spin_lock for the qdf record. + * Fills up rec->data with |metadata|data| * * Return: none */ -static void qdf_dp_add_record(enum QDF_DP_TRACE_ID code, uint8_t *data, - uint8_t size, uint8_t pdev_id, bool print) +static void qdf_dp_fill_record_data + (struct qdf_dp_trace_record_s *rec, + uint8_t *data, uint8_t data_size, + uint8_t *meta_data, uint8_t metadata_size) +{ + int32_t available = QDF_DP_TRACE_RECORD_SIZE; + uint8_t *rec_data = rec->data; + uint8_t data_to_copy = 0; + + qdf_mem_set(rec_data, QDF_DP_TRACE_RECORD_SIZE, 0); + + /* copy meta data */ + if (meta_data) { + if (metadata_size > available) { + QDF_TRACE_WARN(QDF_MODULE_ID_QDF, + "%s: meta data does not fit into the record", + __func__); + goto end; + } + qdf_mem_copy(rec_data, meta_data, metadata_size); + available = available - metadata_size; + } else { + metadata_size = 0; + } + + /* copy data */ + if (data && (data_size > 0) && (available > 0)) { + data_to_copy = data_size; + if (data_size > available) + data_to_copy = available; + qdf_mem_copy(&rec_data[metadata_size], data, data_to_copy); + } +end: + rec->size = data_to_copy; +} + +/** + * qdf_dp_add_record() - add dp trace record + * @code: dptrace code + * @pdev_id: pdev_id + * @print: true to print it in kmsg + * @data: data pointer + * @data_size: size of data to be copied + * @meta_data: meta data to be prepended to data + * @metadata_size: sizeof meta data + * @print: whether to print record + * + * Return: none + */ +static void qdf_dp_add_record(enum QDF_DP_TRACE_ID code, uint8_t pdev_id, + uint8_t *data, uint8_t data_size, + uint8_t *meta_data, uint8_t metadata_size, + bool print) + { struct qdf_dp_trace_record_s *rec = NULL; int index; + bool print_this_record = false; + u8 info = 0; + + if (code >= QDF_DP_TRACE_MAX) { + QDF_TRACE_ERROR(QDF_MODULE_ID_QDF, + "invalid record code %u, max code %u", + code, QDF_DP_TRACE_MAX); + return; + } spin_lock_bh(&l_dp_trace_lock); @@ -1252,47 +1372,35 @@ static void qdf_dp_add_record(enum QDF_DP_TRACE_ID code, uint8_t *data, rec->code = code; rec->pdev_id = pdev_id; rec->size = 0; - if (data != NULL && size > 0) { - if (size > QDF_DP_TRACE_RECORD_SIZE) - size = QDF_DP_TRACE_RECORD_SIZE; - - rec->size = size; - qdf_mem_copy(rec->data, data, size); - } - qdf_get_time_of_the_day_in_hr_min_sec_usec(rec->time, - sizeof(rec->time)); + qdf_dp_fill_record_data(rec, data, data_size, + meta_data, metadata_size); + rec->time = qdf_get_log_timestamp(); rec->pid = (in_interrupt() ? 0 : current->pid); - spin_unlock_bh(&l_dp_trace_lock); - if (rec->code >= QDF_DP_TRACE_MAX) { - QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, - "invalid record code %u, max code %u", rec->code, - QDF_DP_TRACE_MAX); + QDF_TRACE_ERROR(QDF_MODULE_ID_QDF, + "invalid record code %u, max code %u", + rec->code, QDF_DP_TRACE_MAX); return; } - if (print == true) { - qdf_dp_trace_cb_table[rec->code] (rec, index, - QDF_TRACE_DEFAULT_PDEV_ID, true); - return; - } - - if (g_qdf_dp_trace_data.live_mode_config) { - spin_lock_bh(&l_dp_trace_lock); + if (print || g_qdf_dp_trace_data.force_live_mode) { + print_this_record = true; + } else if (g_qdf_dp_trace_data.live_mode == 1) { + print_this_record = true; g_qdf_dp_trace_data.print_pkt_cnt++; - if ((g_qdf_dp_trace_data.live_mode == 1) && - (g_qdf_dp_trace_data.print_pkt_cnt > - g_qdf_dp_trace_data.high_tput_thresh)) + if (g_qdf_dp_trace_data.print_pkt_cnt > + g_qdf_dp_trace_data.high_tput_thresh) { g_qdf_dp_trace_data.live_mode = 0; - spin_unlock_bh(&l_dp_trace_lock); + info |= QDF_DP_TRACE_RECORD_INFO_THROTTLED; + } } + spin_unlock_bh(&l_dp_trace_lock); - if (g_qdf_dp_trace_data.live_mode == true) { + info |= QDF_DP_TRACE_RECORD_INFO_LIVE; + if (print_this_record) qdf_dp_trace_cb_table[rec->code] (rec, index, - QDF_TRACE_DEFAULT_PDEV_ID, true); - return; - } + QDF_TRACE_DEFAULT_PDEV_ID, info); } @@ -1572,40 +1680,27 @@ bool qdf_dp_trace_log_pkt(uint8_t session_id, struct sk_buff *skb, } qdf_export_symbol(qdf_dp_trace_log_pkt); -/** - * qdf_dp_display_mgmt_pkt() - display proto packet - * @record: dptrace record - * @index: index - * @live : live mode or dump mode - * - * Return: none - */ void qdf_dp_display_mgmt_pkt(struct qdf_dp_trace_record_s *record, - uint16_t index, uint8_t pdev_id, bool live) + uint16_t index, uint8_t pdev_id, uint8_t info) { + int loc; + char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE]; struct qdf_dp_trace_mgmt_buf *buf = (struct qdf_dp_trace_mgmt_buf *)record->data; - DPTRACE_PRINT("DPT: %04d: %s [%d] [%s %s %s]", - index, - (live == true) ? " " : record->time, - buf->vdev_id, - qdf_dp_code_to_string(record->code), - qdf_dp_type_to_str(buf->type), - qdf_dp_subtype_to_str(buf->subtype)); + qdf_mem_set(prepend_str, 0, sizeof(prepend_str)); + loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), + index, info, record); + + DPTRACE_PRINT("%s [%d] [%s %s]", + prepend_str, + buf->vdev_id, + qdf_dp_type_to_str(buf->type), + qdf_dp_subtype_to_str(buf->subtype)); } qdf_export_symbol(qdf_dp_display_mgmt_pkt); -/** - * qdf_dp_trace_mgmt_pkt() - record mgmt packet - * @code: dptrace code - * @vdev_id: vdev id - * @pdev_id: pdev_id - * @type: proto type - * @subtype: proto subtype - * - * Return: none - */ + void qdf_dp_trace_mgmt_pkt(enum QDF_DP_TRACE_ID code, uint8_t vdev_id, uint8_t pdev_id, enum qdf_proto_type type, enum qdf_proto_subtype subtype) @@ -1622,31 +1717,27 @@ void qdf_dp_trace_mgmt_pkt(enum QDF_DP_TRACE_ID code, uint8_t vdev_id, buf.type = type; buf.subtype = subtype; buf.vdev_id = vdev_id; - qdf_dp_add_record(code, (uint8_t *)&buf, buf_size, pdev_id, true); + qdf_dp_add_record(code, pdev_id, (uint8_t *)&buf, buf_size, + NULL, 0, true); } qdf_export_symbol(qdf_dp_trace_mgmt_pkt); -/** - * qdf_dp_display_event_record() - display event records - * @record: dptrace record - * @index: index - * @live : live mode or dump mode - * - * Return: none - */ void qdf_dp_display_event_record(struct qdf_dp_trace_record_s *record, - uint16_t index, uint8_t pdev_id, bool live) + uint16_t index, uint8_t pdev_id, uint8_t info) { + char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE]; struct qdf_dp_trace_event_buf *buf = (struct qdf_dp_trace_event_buf *)record->data; - DPTRACE_PRINT("DPT: %04d: %s [%d] [%s %s %s]", - index, - (live == true) ? "" : record->time, - buf->vdev_id, - qdf_dp_code_to_string(record->code), - qdf_dp_type_to_str(buf->type), - qdf_dp_subtype_to_str(buf->subtype)); + qdf_mem_set(prepend_str, 0, sizeof(prepend_str)); + qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), + index, info, record); + + DPTRACE_PRINT("%s [%d] [%s %s]", + prepend_str, + buf->vdev_id, + qdf_dp_type_to_str(buf->type), + qdf_dp_subtype_to_str(buf->subtype)); } qdf_export_symbol(qdf_dp_display_event_record); @@ -1676,50 +1767,34 @@ void qdf_dp_trace_record_event(enum QDF_DP_TRACE_ID code, uint8_t vdev_id, buf.type = type; buf.subtype = subtype; buf.vdev_id = vdev_id; - qdf_dp_add_record(code, (uint8_t *)&buf, buf_size, pdev_id, true); + qdf_dp_add_record(code, pdev_id, + (uint8_t *)&buf, buf_size, NULL, 0, true); } qdf_export_symbol(qdf_dp_trace_record_event); -/** - * qdf_dp_display_proto_pkt() - display proto packet - * @record: dptrace record - * @index: index - * @live : live mode or dump mode - * - * Return: none - */ + void qdf_dp_display_proto_pkt(struct qdf_dp_trace_record_s *record, - uint16_t index, uint8_t pdev_id, bool live) + uint16_t index, uint8_t pdev_id, uint8_t info) { + int loc; + char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE]; struct qdf_dp_trace_proto_buf *buf = (struct qdf_dp_trace_proto_buf *)record->data; - DPTRACE_PRINT("DPT: %04d: %s [%d] [%s%s] SA: " QDF_MAC_ADDR_STR - " %s DA: " QDF_MAC_ADDR_STR, - index, - (live == true) ? "" : record->time, + qdf_mem_set(prepend_str, 0, sizeof(prepend_str)); + loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), + index, info, record); + DPTRACE_PRINT("%s [%d] [%s] SA: " + QDF_MAC_ADDR_STR " %s DA: " + QDF_MAC_ADDR_STR, + prepend_str, buf->vdev_id, - qdf_dp_code_to_string(record->code), qdf_dp_subtype_to_str(buf->subtype), QDF_MAC_ADDR_ARRAY(buf->sa.bytes), qdf_dp_dir_to_str(buf->dir), QDF_MAC_ADDR_ARRAY(buf->da.bytes)); } qdf_export_symbol(qdf_dp_display_proto_pkt); -/** - * qdf_dp_trace_proto_pkt() - record proto packet - * @code: dptrace code - * @vdev_id: vdev id - * @sa: source mac address - * @da: destination mac address - * @type: proto type - * @subtype: proto subtype - * @dir: direction - * @pdev_id: pdev id - * @print: to print this proto pkt or not - * - * Return: none - */ void qdf_dp_trace_proto_pkt(enum QDF_DP_TRACE_ID code, uint8_t vdev_id, uint8_t *sa, uint8_t *da, enum qdf_proto_type type, enum qdf_proto_subtype subtype, enum qdf_proto_dir dir, @@ -1740,37 +1815,35 @@ void qdf_dp_trace_proto_pkt(enum QDF_DP_TRACE_ID code, uint8_t vdev_id, buf.type = type; buf.subtype = subtype; buf.vdev_id = vdev_id; - qdf_dp_add_record(code, (uint8_t *)&buf, buf_size, pdev_id, print); + qdf_dp_add_record(code, pdev_id, + (uint8_t *)&buf, buf_size, NULL, 0, print); } qdf_export_symbol(qdf_dp_trace_proto_pkt); -/** - * qdf_dp_display_ptr_record() - display record - * @record: dptrace record - * @index: index - * @live : live mode or dump mode - * - * Return: none - */ void qdf_dp_display_ptr_record(struct qdf_dp_trace_record_s *record, - uint16_t index, uint8_t pdev_id, bool live) + uint16_t index, uint8_t pdev_id, uint8_t info) { - char prepend_str[100] = {'\0'}; + int loc; + char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE]; struct qdf_dp_trace_ptr_buf *buf = (struct qdf_dp_trace_ptr_buf *)record->data; - snprintf(prepend_str, sizeof(prepend_str), - "%04d: %s [%s] [msdu id %d %s %d]", - index, - (live == true) ? "" : record->time, - qdf_dp_code_to_string(record->code), buf->msdu_id, - (record->code == QDF_DP_TRACE_FREE_PACKET_PTR_RECORD) ? - "status" : "vdev_id", - buf->status); + qdf_mem_set(prepend_str, 0, sizeof(prepend_str)); + loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), + index, info, record); - if (live == true) { + if (loc < sizeof(prepend_str)) + scnprintf(&prepend_str[loc], sizeof(prepend_str) - loc, + "[msdu id %d %s %d]", + buf->msdu_id, + (record->code == + QDF_DP_TRACE_FREE_PACKET_PTR_RECORD) ? + "status" : "vdev_id", + buf->status); + + if (info & QDF_DP_TRACE_RECORD_INFO_LIVE) { /* In live mode donot dump the contents of the cookie */ - DPTRACE_PRINT("DPT: %s", prepend_str); + DPTRACE_PRINT("%s", prepend_str); } else { dump_dp_hex_trace(prepend_str, (uint8_t *)&buf->cookie, sizeof(buf->cookie)); @@ -1805,37 +1878,44 @@ void qdf_dp_trace_ptr(qdf_nbuf_t nbuf, enum QDF_DP_TRACE_ID code, qdf_mem_copy(&buf.cookie, data, size); buf.msdu_id = msdu_id; buf.status = status; - qdf_dp_add_record(code, (uint8_t *)&buf, buf_size, pdev_id, - QDF_NBUF_CB_DP_TRACE_PRINT(nbuf)); + qdf_dp_add_record(code, pdev_id, (uint8_t *)&buf, buf_size, NULL, 0, + QDF_NBUF_CB_DP_TRACE_PRINT(nbuf)); } qdf_export_symbol(qdf_dp_trace_ptr); -/** - * qdf_dp_display_trace() - Displays a record in DP trace - * @pRecord : pointer to a record in DP trace - * @recIndex : record index - * @live : live mode or dump mode - * - * Return: None - */ -void qdf_dp_display_record(struct qdf_dp_trace_record_s *pRecord, - uint16_t recIndex, uint8_t pdev_id, bool live) - +void qdf_dp_trace_data_pkt(qdf_nbuf_t nbuf, uint8_t pdev_id, + enum QDF_DP_TRACE_ID code, uint16_t msdu_id, + enum qdf_proto_dir dir) { - char prepend_str[50] = {'\0'}; + struct qdf_dp_trace_data_buf buf; - if (!(pdev_id == QDF_TRACE_DEFAULT_PDEV_ID || - pdev_id == pRecord->pdev_id)) + buf.msdu_id = msdu_id; + if (!qdf_dp_enable_check(nbuf, code, dir)) return; - snprintf(prepend_str, sizeof(prepend_str), - "%04d PDEV_ID = %02d: %s %s", - recIndex, - pRecord->pdev_id, - (live == true) ? "" : pRecord->time, - qdf_dp_code_to_string(pRecord->code)); + qdf_dp_add_record(code, pdev_id, + qdf_nbuf_data(nbuf), nbuf->len - nbuf->data_len, + (uint8_t *)&buf, sizeof(struct qdf_dp_trace_data_buf), + (nbuf) ? QDF_NBUF_CB_DP_TRACE_PRINT(nbuf) : false); +} - switch (pRecord->code) { +qdf_export_symbol(qdf_dp_trace_data_pkt); + +void qdf_dp_display_record(struct qdf_dp_trace_record_s *record, + uint16_t index, uint8_t pdev_id, uint8_t info) +{ + int loc; + char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE]; + + if (!(pdev_id == QDF_TRACE_DEFAULT_PDEV_ID || + pdev_id == record->pdev_id)) + return; + + qdf_mem_set(prepend_str, 0, sizeof(prepend_str)); + loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), + index, info, record); + + switch (record->code) { case QDF_DP_TRACE_HDD_TX_TIMEOUT: DPTRACE_PRINT(" %s: HDD TX Timeout", prepend_str); break; @@ -1845,18 +1925,37 @@ void qdf_dp_display_record(struct qdf_dp_trace_record_s *pRecord, case QDF_DP_TRACE_CE_FAST_PACKET_ERR_RECORD: DPTRACE_PRINT(" %s: CE Fast Packet Error", prepend_str); break; - case QDF_DP_TRACE_HDD_TX_PACKET_RECORD: - case QDF_DP_TRACE_HDD_RX_PACKET_RECORD: case QDF_DP_TRACE_LI_DP_TX_PACKET_RECORD: case QDF_DP_TRACE_LI_DP_RX_PACKET_RECORD: case QDF_DP_TRACE_LI_DP_NULL_RX_PACKET_RECORD: default: - dump_dp_hex_trace(prepend_str, pRecord->data, pRecord->size); + dump_dp_hex_trace(prepend_str, record->data, record->size); break; }; } qdf_export_symbol(qdf_dp_display_record); +void +qdf_dp_display_data_pkt_record(struct qdf_dp_trace_record_s *record, + uint16_t rec_index, uint8_t pdev_id, + uint8_t info) +{ + int loc; + char prepend_str[DP_TRACE_META_DATA_STRLEN + 10]; + struct qdf_dp_trace_data_buf *buf = + (struct qdf_dp_trace_data_buf *)record->data; + + qdf_mem_set(prepend_str, 0, sizeof(prepend_str)); + + loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), + rec_index, info, record); + if (loc < sizeof(prepend_str)) + loc += snprintf(&prepend_str[loc], sizeof(prepend_str) - loc, + "[%d]", buf->msdu_id); + dump_dp_hex_trace(prepend_str, + &record->data[sizeof(struct qdf_dp_trace_data_buf)], + record->size); +} /** * qdf_dp_trace() - Stores the data in buffer @@ -1875,8 +1974,8 @@ void qdf_dp_trace(qdf_nbuf_t nbuf, enum QDF_DP_TRACE_ID code, uint8_t pdev_id, if (qdf_dp_enable_check(nbuf, code, dir) == false) return; - qdf_dp_add_record(code, data, size, pdev_id, - (nbuf != NULL) ? QDF_NBUF_CB_DP_TRACE_PRINT(nbuf) : false); + qdf_dp_add_record(code, pdev_id, qdf_nbuf_data(nbuf), size, NULL, 0, + (nbuf) ? QDF_NBUF_CB_DP_TRACE_PRINT(nbuf) : false); } qdf_export_symbol(qdf_dp_trace); @@ -1900,7 +1999,7 @@ qdf_export_symbol(qdf_dp_trace_spin_lock_init); */ void qdf_dp_trace_disable_live_mode(void) { - g_qdf_dp_trace_data.live_mode = 0; + g_qdf_dp_trace_data.force_live_mode = 0; } qdf_export_symbol(qdf_dp_trace_disable_live_mode); @@ -1911,7 +2010,7 @@ qdf_export_symbol(qdf_dp_trace_disable_live_mode); */ void qdf_dp_trace_enable_live_mode(void) { - g_qdf_dp_trace_data.live_mode = 1; + g_qdf_dp_trace_data.force_live_mode = 1; } qdf_export_symbol(qdf_dp_trace_enable_live_mode); @@ -1998,14 +2097,18 @@ static void qdf_dpt_display_proto_pkt_debugfs(qdf_debugfs_file_t file, struct qdf_dp_trace_record_s *record, uint32_t index) { + int loc; + char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE]; struct qdf_dp_trace_proto_buf *buf = - (struct qdf_dp_trace_proto_buf *)record->data; + (struct qdf_dp_trace_proto_buf *)record->data; - qdf_debugfs_printf(file, "DPT: %04d: %s [%d] [%s%s] SA: " + loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), + index, 0, record); + qdf_debugfs_printf(file, "%s [%d] [%s] SA: " QDF_MAC_ADDR_STR " %s DA: " QDF_MAC_ADDR_STR, - index, record->time, buf->vdev_id, - qdf_dp_code_to_string(record->code), + prepend_str, + buf->vdev_id, qdf_dp_subtype_to_str(buf->subtype), QDF_MAC_ADDR_ARRAY(buf->sa.bytes), qdf_dp_dir_to_str(buf->dir), @@ -2025,12 +2128,18 @@ static void qdf_dpt_display_mgmt_pkt_debugfs(qdf_debugfs_file_t file, struct qdf_dp_trace_record_s *record, uint32_t index) { + + int loc; + char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE]; struct qdf_dp_trace_mgmt_buf *buf = (struct qdf_dp_trace_mgmt_buf *)record->data; - qdf_debugfs_printf(file, "DPT: %04d: %s [%d] [%s %s %s]\n", - index, record->time, buf->vdev_id, - qdf_dp_code_to_string(record->code), + loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), + index, 0, record); + + qdf_debugfs_printf(file, "%s [%d] [%s %s]\n", + prepend_str, + buf->vdev_id, qdf_dp_type_to_str(buf->type), qdf_dp_subtype_to_str(buf->subtype)); } @@ -2047,12 +2156,15 @@ static void qdf_dpt_display_event_record_debugfs(qdf_debugfs_file_t file, struct qdf_dp_trace_record_s *record, uint32_t index) { + char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE]; struct qdf_dp_trace_event_buf *buf = (struct qdf_dp_trace_event_buf *)record->data; - qdf_debugfs_printf(file, "DPT: %04d: %s [%d] [%s %s %s]\n", - index, record->time, buf->vdev_id, - qdf_dp_code_to_string(record->code), + qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), + index, 0, record); + qdf_debugfs_printf(file, "%s [%d] [%s %s]\n", + prepend_str, + buf->vdev_id, qdf_dp_type_to_str(buf->type), qdf_dp_subtype_to_str(buf->subtype)); } @@ -2069,19 +2181,22 @@ static void qdf_dpt_display_ptr_record_debugfs(qdf_debugfs_file_t file, struct qdf_dp_trace_record_s *record, uint32_t index) { + char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE]; + int loc; + struct qdf_dp_trace_ptr_buf *buf = + (struct qdf_dp_trace_ptr_buf *)record->data; + loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), + index, 0, record); - char prepend_str[100] = {'\0'}; - struct qdf_dp_trace_ptr_buf *buf = - (struct qdf_dp_trace_ptr_buf *)record->data; + if (loc < sizeof(prepend_str)) + scnprintf(&prepend_str[loc], sizeof(prepend_str) - loc, + "[msdu id %d %s %d]", + buf->msdu_id, + (record->code == + QDF_DP_TRACE_FREE_PACKET_PTR_RECORD) ? + "status" : "vdev_id", + buf->status); - snprintf(prepend_str, sizeof(prepend_str), - "%04d: %s [%s] [msdu id %d %s %d]", - index, - record->time, - qdf_dp_code_to_string(record->code), buf->msdu_id, - (record->code == QDF_DP_TRACE_FREE_PACKET_PTR_RECORD) ? - "status" : "vdev_id", - buf->status); qdf_dpt_dump_hex_trace_debugfs(file, prepend_str, (uint8_t *)&buf->cookie, sizeof(buf->cookie)); @@ -2099,14 +2214,11 @@ static void qdf_dpt_display_record_debugfs(qdf_debugfs_file_t file, struct qdf_dp_trace_record_s *record, uint32_t index) { + int loc; + char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE]; - char prepend_str[50] = {'\0'}; - - snprintf(prepend_str, sizeof(prepend_str), - "%04d: %s %s", - index, - record->time, - qdf_dp_code_to_string(record->code)); + loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), + index, 0, record); qdf_dpt_dump_hex_trace_debugfs(file, prepend_str, record->data, record->size); } @@ -2266,6 +2378,8 @@ QDF_STATUS qdf_dpt_dump_stats_debugfs(qdf_debugfs_file_t file, case QDF_DP_TRACE_HDD_TX_PACKET_RECORD: case QDF_DP_TRACE_HDD_RX_PACKET_RECORD: + case QDF_DP_TRACE_TX_PACKET_RECORD: + case QDF_DP_TRACE_RX_PACKET_RECORD: default: qdf_dpt_display_record_debugfs(file, &p_record, i); break;