qcacmn: Dptrace enhancements

* Log EAPOL, ARP, DHCP, MGMT, ROAM Events, ICMP, Data packets,
  TX-Completions by default.
* Set default verbosity as low (existing is high)
* Throttle ICMP and Data packets if threshold exceeds.
* Enable live mode by default. Added ini entry to disable
  it and configure high throughput thresh - gDptraceConfig
* Log only SA and DA for proto packets (and not 32 bytes)
* Format prints to fit in 1 line.

CRs-Fixed: 2051134
Change-Id: I2f82c38f5fda73f440c4c4c760e633904705b5a2
This commit is contained in:
Mohit Khanna
2017-05-15 15:53:33 -07:00
committed by snandini
parent 9b1964e78a
commit 7750a17a55
2 changed files with 364 additions and 173 deletions

View File

@@ -99,9 +99,18 @@ void qdf_trace(uint8_t module, uint8_t code, uint16_t session, uint32_t data);
#define INVALID_QDF_TRACE_ADDR 0xffffffff #define INVALID_QDF_TRACE_ADDR 0xffffffff
#define DEFAULT_QDF_TRACE_DUMP_COUNT 0 #define DEFAULT_QDF_TRACE_DUMP_COUNT 0
/*
* first parameter to iwpriv command - dump_dp_trace
* iwpriv wlan0 dump_dp_trace 0 0 -> dump full buffer
* iwpriv wlan0 dump_dp_trace 1 0 -> enable live view mode
* iwpriv wlan0 dump_dp_trace 2 0 -> clear dp trace buffer
* iwpriv wlan0 dump_dp_trace 3 0 -> disable live view mode
*/
#define DUMP_DP_TRACE 0 #define DUMP_DP_TRACE 0
#define ENABLE_DP_TRACE_LIVE_MODE 1 #define ENABLE_DP_TRACE_LIVE_MODE 1
#define CLEAR_DP_TRACE_BUFFER 2 #define CLEAR_DP_TRACE_BUFFER 2
#define DISABLE_DP_TRACE_LIVE_MODE 3
#ifdef TRACE_RECORD #ifdef TRACE_RECORD
@@ -160,7 +169,7 @@ typedef struct s_qdf_trace_data {
#define QDF_DP_TRACE_VERBOSITY_HIGH 3 #define QDF_DP_TRACE_VERBOSITY_HIGH 3
#define QDF_DP_TRACE_VERBOSITY_MEDIUM 2 #define QDF_DP_TRACE_VERBOSITY_MEDIUM 2
#define QDF_DP_TRACE_VERBOSITY_LOW 1 #define QDF_DP_TRACE_VERBOSITY_LOW 1
#define QDF_DP_TRACE_VERBOSITY_DEFAULT 0 #define QDF_DP_TRACE_VERBOSITY_BASE 0
/** /**
* enum QDF_DP_TRACE_ID - Generic ID to identify various events in data path * enum QDF_DP_TRACE_ID - Generic ID to identify various events in data path
@@ -170,21 +179,24 @@ typedef struct s_qdf_trace_data {
* @QDF_DP_TRACE_DHCP_PACKET_RECORD - record DHCP packet * @QDF_DP_TRACE_DHCP_PACKET_RECORD - record DHCP packet
* @QDF_DP_TRACE_ARP_PACKET_RECORD - record ARP packet * @QDF_DP_TRACE_ARP_PACKET_RECORD - record ARP packet
* @QDF_DP_TRACE_MGMT_PACKET_RECORD - record MGMT pacekt * @QDF_DP_TRACE_MGMT_PACKET_RECORD - record MGMT pacekt
* @QDF_DP_TRACE_ICMP_PACKET_RECORD - record ICMP packet
* QDF_DP_TRACE_EVENT_RECORD - record events * QDF_DP_TRACE_EVENT_RECORD - record events
* @QDF_DP_TRACE_DEFAULT_VERBOSITY - below this are part of default verbosity * @QDF_DP_TRACE_BASE_VERBOSITY - below this are part of base verbosity
* @QDF_DP_TRACE_ICMP_PACKET_RECORD - record ICMP packets
* @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_HDD_TX_TIMEOUT - HDD tx timeout * @QDF_DP_TRACE_HDD_TX_TIMEOUT - HDD tx timeout
* @QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT- SOFTAP 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
* @QDF_DP_TRACE_LOW_VERBOSITY - below this are part of low verbosity
* @QDF_DP_TRACE_HDD_TX_PACKET_PTR_RECORD - HDD layer ptr record * @QDF_DP_TRACE_HDD_TX_PACKET_PTR_RECORD - HDD layer ptr record
* @QDF_DP_TRACE_LI_DP_TX_PACKET_PTR_RECORD - Lithium DP layer ptr record * @QDF_DP_TRACE_LI_DP_TX_PACKET_PTR_RECORD - Lithium DP layer ptr record
* @QDF_DP_TRACE_CE_PACKET_PTR_RECORD - CE layer ptr record * @QDF_DP_TRACE_CE_PACKET_PTR_RECORD - CE layer ptr record
* @QDF_DP_TRACE_CE_FAST_PACKET_PTR_RECORD- CE fastpath ptr record * @QDF_DP_TRACE_CE_FAST_PACKET_PTR_RECORD- CE fastpath ptr record
* @QDF_DP_TRACE_FREE_PACKET_PTR_RECORD - tx completion ptr record
* @QDF_DP_TRACE_RX_HTT_PACKET_PTR_RECORD - HTT RX record * @QDF_DP_TRACE_RX_HTT_PACKET_PTR_RECORD - HTT RX record
* @QDF_DP_TRACE_RX_OFFLOAD_HTT_PACKET_PTR_RECORD- HTT RX offload record * @QDF_DP_TRACE_RX_OFFLOAD_HTT_PACKET_PTR_RECORD- HTT RX offload record
* @QDF_DP_TRACE_RX_HDD_PACKET_PTR_RECORD - HDD RX record * @QDF_DP_TRACE_RX_HDD_PACKET_PTR_RECORD - HDD RX record
* @QDF_DP_TRACE_RX_LI_DP_PACKET_PTR_RECORD - Lithium DP RX record * @QDF_DP_TRACE_RX_LI_DP_PACKET_PTR_RECORD - Lithium DP RX record
* @QDF_DP_TRACE_LOW_VERBOSITY - below this are part of low verbosity * @QDF_DP_TRACE_MED_VERBOSITY - below this are part of med verbosity
* @QDF_DP_TRACE_TXRX_QUEUE_PACKET_PTR_RECORD -tx queue ptr record * @QDF_DP_TRACE_TXRX_QUEUE_PACKET_PTR_RECORD -tx queue ptr record
* @QDF_DP_TRACE_TXRX_PACKET_PTR_RECORD - txrx packet ptr record * @QDF_DP_TRACE_TXRX_PACKET_PTR_RECORD - txrx packet ptr record
* @QDF_DP_TRACE_TXRX_FAST_PACKET_PTR_RECORD - txrx fast path record * @QDF_DP_TRACE_TXRX_FAST_PACKET_PTR_RECORD - txrx fast path record
@@ -192,9 +204,6 @@ typedef struct s_qdf_trace_data {
* @QDF_DP_TRACE_HTC_PACKET_PTR_RECORD - htc packet ptr record * @QDF_DP_TRACE_HTC_PACKET_PTR_RECORD - htc packet ptr record
* @QDF_DP_TRACE_HIF_PACKET_PTR_RECORD - hif packet ptr record * @QDF_DP_TRACE_HIF_PACKET_PTR_RECORD - hif packet ptr record
* @QDF_DP_TRACE_RX_TXRX_PACKET_PTR_RECORD - txrx packet ptr record * @QDF_DP_TRACE_RX_TXRX_PACKET_PTR_RECORD - txrx packet ptr record
* @QDF_DP_TRACE_MED_VERBOSITY - below this are part of med verbosity
* @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_LI_DP_TX_PACKET_RECORD - record 32 bytes of tx pkt at LI_DP * @QDF_DP_TRACE_LI_DP_TX_PACKET_RECORD - record 32 bytes of tx pkt at LI_DP
* @QDF_DP_TRACE_LI_DP_RX_PACKET_RECORD - record 32 bytes of rx pkt at LI_DP * @QDF_DP_TRACE_LI_DP_RX_PACKET_RECORD - record 32 bytes of rx pkt at LI_DP
* @QDF_DP_TRACE_LI_DP_NULL_RX_PACKET_RECORD * @QDF_DP_TRACE_LI_DP_NULL_RX_PACKET_RECORD
@@ -208,21 +217,24 @@ enum QDF_DP_TRACE_ID {
QDF_DP_TRACE_DHCP_PACKET_RECORD, QDF_DP_TRACE_DHCP_PACKET_RECORD,
QDF_DP_TRACE_ARP_PACKET_RECORD, QDF_DP_TRACE_ARP_PACKET_RECORD,
QDF_DP_TRACE_MGMT_PACKET_RECORD, QDF_DP_TRACE_MGMT_PACKET_RECORD,
QDF_DP_TRACE_ICMP_PACKET_RECORD,
QDF_DP_TRACE_EVENT_RECORD, QDF_DP_TRACE_EVENT_RECORD,
QDF_DP_TRACE_DEFAULT_VERBOSITY, QDF_DP_TRACE_BASE_VERBOSITY,
QDF_DP_TRACE_ICMP_PACKET_RECORD,
QDF_DP_TRACE_HDD_TX_PACKET_RECORD,
QDF_DP_TRACE_HDD_RX_PACKET_RECORD,
QDF_DP_TRACE_HDD_TX_TIMEOUT, QDF_DP_TRACE_HDD_TX_TIMEOUT,
QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT, QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT,
QDF_DP_TRACE_FREE_PACKET_PTR_RECORD,
QDF_DP_TRACE_LOW_VERBOSITY,
QDF_DP_TRACE_HDD_TX_PACKET_PTR_RECORD, QDF_DP_TRACE_HDD_TX_PACKET_PTR_RECORD,
QDF_DP_TRACE_LI_DP_TX_PACKET_PTR_RECORD, QDF_DP_TRACE_LI_DP_TX_PACKET_PTR_RECORD,
QDF_DP_TRACE_RX_HDD_PACKET_PTR_RECORD,
QDF_DP_TRACE_CE_PACKET_PTR_RECORD, QDF_DP_TRACE_CE_PACKET_PTR_RECORD,
QDF_DP_TRACE_CE_FAST_PACKET_PTR_RECORD, QDF_DP_TRACE_CE_FAST_PACKET_PTR_RECORD,
QDF_DP_TRACE_FREE_PACKET_PTR_RECORD,
QDF_DP_TRACE_RX_HTT_PACKET_PTR_RECORD, QDF_DP_TRACE_RX_HTT_PACKET_PTR_RECORD,
QDF_DP_TRACE_RX_OFFLOAD_HTT_PACKET_PTR_RECORD, QDF_DP_TRACE_RX_OFFLOAD_HTT_PACKET_PTR_RECORD,
QDF_DP_TRACE_RX_HDD_PACKET_PTR_RECORD,
QDF_DP_TRACE_RX_LI_DP_PACKET_PTR_RECORD, QDF_DP_TRACE_RX_LI_DP_PACKET_PTR_RECORD,
QDF_DP_TRACE_LOW_VERBOSITY, QDF_DP_TRACE_MED_VERBOSITY,
QDF_DP_TRACE_TXRX_QUEUE_PACKET_PTR_RECORD, QDF_DP_TRACE_TXRX_QUEUE_PACKET_PTR_RECORD,
QDF_DP_TRACE_TXRX_PACKET_PTR_RECORD, QDF_DP_TRACE_TXRX_PACKET_PTR_RECORD,
QDF_DP_TRACE_TXRX_FAST_PACKET_PTR_RECORD, QDF_DP_TRACE_TXRX_FAST_PACKET_PTR_RECORD,
@@ -230,9 +242,6 @@ enum QDF_DP_TRACE_ID {
QDF_DP_TRACE_HTC_PACKET_PTR_RECORD, QDF_DP_TRACE_HTC_PACKET_PTR_RECORD,
QDF_DP_TRACE_HIF_PACKET_PTR_RECORD, QDF_DP_TRACE_HIF_PACKET_PTR_RECORD,
QDF_DP_TRACE_RX_TXRX_PACKET_PTR_RECORD, QDF_DP_TRACE_RX_TXRX_PACKET_PTR_RECORD,
QDF_DP_TRACE_MED_VERBOSITY,
QDF_DP_TRACE_HDD_TX_PACKET_RECORD,
QDF_DP_TRACE_HDD_RX_PACKET_RECORD,
QDF_DP_TRACE_LI_DP_TX_PACKET_RECORD, QDF_DP_TRACE_LI_DP_TX_PACKET_RECORD,
QDF_DP_TRACE_LI_DP_RX_PACKET_RECORD, QDF_DP_TRACE_LI_DP_RX_PACKET_RECORD,
QDF_DP_TRACE_LI_DP_NULL_RX_PACKET_RECORD, QDF_DP_TRACE_LI_DP_NULL_RX_PACKET_RECORD,
@@ -333,6 +342,17 @@ struct qdf_dp_trace_record_s {
* @verbosity : defines verbosity level * @verbosity : defines verbosity level
* @enable: enable/disable DP trace * @enable: enable/disable DP trace
* @count: current packet number * @count: current packet number
* @live_mode_config: configuration as received during initialization
* @live_mode: current live mode, enabled or disabled.
* @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,
* for determining if high_tput_thresh has been crossed. ~1s
*.@arp_req: stats for arp reqs
*.@arp_resp: stats for arp resps
*.@icmp_req: stats for icmp reqs
*.@icmp_req: stats for icmp resps
*/ */
struct s_qdf_dp_trace_data { struct s_qdf_dp_trace_data {
uint32_t head; uint32_t head;
@@ -342,9 +362,18 @@ struct s_qdf_dp_trace_data {
uint8_t no_of_record; uint8_t no_of_record;
uint8_t verbosity; uint8_t verbosity;
bool enable; bool enable;
bool live_mode_config;
bool live_mode;
uint8_t print_pkt_cnt;
uint8_t high_tput_thresh;
uint16_t thresh_time_limit;
/* Stats */
uint32_t tx_count; uint32_t tx_count;
uint32_t rx_count; uint32_t rx_count;
bool live_mode; uint32_t arp_req;
uint32_t arp_resp;
uint32_t icmp_req;
uint32_t icmp_resp;
}; };
@@ -401,9 +430,11 @@ void qdf_trace_dump_all(void *, uint8_t, uint8_t, uint32_t, uint32_t);
void qdf_dp_set_proto_bitmap(uint32_t val); void qdf_dp_set_proto_bitmap(uint32_t val);
void qdf_dp_trace_set_verbosity(uint32_t val); void qdf_dp_trace_set_verbosity(uint32_t val);
void qdf_dp_set_no_of_record(uint32_t val); void qdf_dp_set_no_of_record(uint32_t val);
void qdf_dp_trace_log_pkt(uint8_t session_id, struct sk_buff *skb, bool qdf_dp_trace_log_pkt(uint8_t session_id, struct sk_buff *skb,
enum qdf_proto_dir dir, uint8_t pdev_id); enum qdf_proto_dir dir, uint8_t pdev_id);
void qdf_dp_trace_init(void); void qdf_dp_trace_init(bool live_mode_config, uint8_t thresh,
uint16_t time_limit, uint8_t verbosity,
uint8_t proto_bitmap);
void qdf_dp_trace_spin_lock_init(void); void qdf_dp_trace_spin_lock_init(void);
void qdf_dp_trace_set_value(uint8_t proto_bitmap, uint8_t no_of_records, void qdf_dp_trace_set_value(uint8_t proto_bitmap, uint8_t no_of_records,
uint8_t verbosity); uint8_t verbosity);
@@ -412,15 +443,17 @@ void qdf_dp_trace(qdf_nbuf_t nbuf, enum QDF_DP_TRACE_ID code, uint8_t pdev_id,
uint8_t *data, uint8_t size, enum qdf_proto_dir dir); uint8_t *data, uint8_t size, enum qdf_proto_dir dir);
void qdf_dp_trace_dump_all(uint32_t count, uint8_t pdev_id); void qdf_dp_trace_dump_all(uint32_t count, uint8_t pdev_id);
typedef void (*tp_qdf_dp_trace_cb)(struct qdf_dp_trace_record_s*, typedef void (*tp_qdf_dp_trace_cb)(struct qdf_dp_trace_record_s*,
uint16_t, uint8_t); uint16_t, uint8_t, bool live);
void qdf_dp_display_record(struct qdf_dp_trace_record_s *record, void qdf_dp_display_record(struct qdf_dp_trace_record_s *record,
uint16_t index, uint8_t pdev_id); uint16_t index, uint8_t pdev_id, bool live);
void qdf_dp_trace_ptr(qdf_nbuf_t nbuf, enum QDF_DP_TRACE_ID code, 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, uint8_t pdev_id, uint8_t *data, uint8_t size, uint16_t msdu_id,
uint16_t status); 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, void qdf_dp_display_ptr_record(struct qdf_dp_trace_record_s *pRecord,
uint16_t recIndex, uint8_t pdev_id); uint16_t recIndex, uint8_t pdev_id, bool live);
void qdf_dp_display_proto_pkt(struct qdf_dp_trace_record_s *record,
uint16_t index, uint8_t pdev_id, bool live);
uint8_t qdf_dp_get_proto_bitmap(void); uint8_t qdf_dp_get_proto_bitmap(void);
uint8_t qdf_dp_get_verbosity(void); uint8_t qdf_dp_get_verbosity(void);
uint8_t qdf_dp_get_no_of_record(void); uint8_t qdf_dp_get_no_of_record(void);
@@ -428,29 +461,31 @@ void
qdf_dp_trace_proto_pkt(enum QDF_DP_TRACE_ID code, uint8_t vdev_id, 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, uint8_t *sa, uint8_t *da, enum qdf_proto_type type,
enum qdf_proto_subtype subtype, enum qdf_proto_dir dir, enum qdf_proto_subtype subtype, enum qdf_proto_dir dir,
uint8_t pdev_id); uint8_t pdev_id, bool print);
void qdf_dp_display_proto_pkt(struct qdf_dp_trace_record_s *record, void qdf_dp_trace_disable_live_mode(void);
uint16_t index, uint8_t pdev_id);
void qdf_dp_trace_enable_live_mode(void); void qdf_dp_trace_enable_live_mode(void);
void qdf_dp_trace_clear_buffer(void); void qdf_dp_trace_clear_buffer(void);
void qdf_dp_trace_mgmt_pkt(enum QDF_DP_TRACE_ID code, uint8_t vdev_id, 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, uint8_t pdev_id, enum qdf_proto_type type,
enum qdf_proto_subtype subtype); enum qdf_proto_subtype subtype);
void qdf_dp_display_mgmt_pkt(struct qdf_dp_trace_record_s *record, void qdf_dp_display_mgmt_pkt(struct qdf_dp_trace_record_s *record,
uint16_t index, uint8_t pdev_id); uint16_t index, uint8_t pdev_id, bool live);
void qdf_dp_display_event_record(struct qdf_dp_trace_record_s *record, void qdf_dp_display_event_record(struct qdf_dp_trace_record_s *record,
uint16_t index, uint8_t pdev_id); uint16_t index, uint8_t pdev_id, bool live);
void qdf_dp_trace_record_event(enum QDF_DP_TRACE_ID code, uint8_t vdev_id, 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, uint8_t pdev_id, enum qdf_proto_type type,
enum qdf_proto_subtype subtype); enum qdf_proto_subtype subtype);
#else #else
static inline static inline
void qdf_dp_trace_log_pkt(uint8_t session_id, struct sk_buff *skb, bool qdf_dp_trace_log_pkt(uint8_t session_id, struct sk_buff *skb,
enum qdf_proto_dir dir, uint8_t pdev_id) enum qdf_proto_dir dir, uint8_t pdev_id)
{ {
return false;
} }
static inline static inline
void qdf_dp_trace_init(void) void qdf_dp_trace_init(bool live_mode_config, uint8_t thresh,
uint16_t time_limit, uint8_t verbosity,
uint8_t proto_bitmap)
{ {
} }
static inline static inline
@@ -467,11 +502,21 @@ void qdf_dp_trace_dump_all(uint32_t count, uint8_t pdev_id)
{ {
} }
static inline
void qdf_dp_trace_disable_live_mode(void)
{
}
static inline static inline
void qdf_dp_trace_enable_live_mode(void) void qdf_dp_trace_enable_live_mode(void)
{ {
} }
static inline
void qdf_dp_trace_throttle_live_mode(bool high_bw_request)
{
}
static inline static inline
void qdf_dp_trace_clear_buffer(void) void qdf_dp_trace_clear_buffer(void)
{ {

View File

@@ -592,7 +592,7 @@ void qdf_trace_dump_all(void *p_mac, uint8_t code, uint8_t session,
} }
QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_INFO, QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_INFO,
"Total Records: %d, Head: %d, Tail: %d", "DPT: Total Records: %d, Head: %d, Tail: %d",
g_qdf_trace_data.num, g_qdf_trace_data.head, g_qdf_trace_data.num, g_qdf_trace_data.head,
g_qdf_trace_data.tail); g_qdf_trace_data.tail);
@@ -728,7 +728,7 @@ EXPORT_SYMBOL(qdf_state_info_dump_all);
#ifdef CONFIG_DP_TRACE #ifdef CONFIG_DP_TRACE
static void qdf_dp_unused(struct qdf_dp_trace_record_s *record, static void qdf_dp_unused(struct qdf_dp_trace_record_s *record,
uint16_t index, uint8_t pdev_id) uint16_t index, uint8_t pdev_id, bool live)
{ {
qdf_print("%s: QDF_DP_TRACE_MAX event should not be generated", qdf_print("%s: QDF_DP_TRACE_MAX event should not be generated",
__func__); __func__);
@@ -736,16 +736,39 @@ static void qdf_dp_unused(struct qdf_dp_trace_record_s *record,
/** /**
* qdf_dp_trace_init() - enables the DP trace * qdf_dp_trace_init() - enables the DP trace
* Called during driver load and it enables DP trace * @live_mode_config: live mode configuration
* @thresh: high throughput threshold for disabling live mode
* @thresh_time_limit: max time to wait before deciding if thresh is crossed
* @verbosity: dptrace verbosity level
* @proto_bitmap: bitmap to enable/disable specific protocols
* *
* Called during driver load to init dptrace
*
* A brief note on the 'thresh' param -
* Total # of packets received in a bandwidth timer interval beyond which
* DP Trace logging for data packets (including ICMP) will be disabled.
* In memory logging will still continue for these packets. Other packets for
* which proto.bitmap is set will continue to be recorded in logs and in memory.
* Return: None * Return: None
*/ */
void qdf_dp_trace_init(void) void qdf_dp_trace_init(bool live_mode_config, uint8_t thresh,
uint16_t time_limit, uint8_t verbosity,
uint8_t proto_bitmap)
{ {
uint8_t i; uint8_t i;
qdf_dp_trace_spin_lock_init(); qdf_dp_trace_spin_lock_init();
qdf_dp_trace_clear_buffer(); qdf_dp_trace_clear_buffer();
g_qdf_dp_trace_data.enable = true;
g_qdf_dp_trace_data.no_of_record = 1;
g_qdf_dp_trace_data.live_mode_config = live_mode_config;
g_qdf_dp_trace_data.live_mode = live_mode_config;
g_qdf_dp_trace_data.high_tput_thresh = thresh;
g_qdf_dp_trace_data.thresh_time_limit = time_limit;
g_qdf_dp_trace_data.proto_bitmap = proto_bitmap;
g_qdf_dp_trace_data.verbosity = verbosity;
for (i = 0; i < ARRAY_SIZE(qdf_dp_trace_cb_table); i++) 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[i] = qdf_dp_display_record;
@@ -871,8 +894,8 @@ static bool qdf_dp_trace_enable_track(enum QDF_DP_TRACE_ID code)
if (code <= QDF_DP_TRACE_LOW_VERBOSITY) if (code <= QDF_DP_TRACE_LOW_VERBOSITY)
return true; return true;
return false; return false;
case QDF_DP_TRACE_VERBOSITY_DEFAULT: case QDF_DP_TRACE_VERBOSITY_BASE:
if (code <= QDF_DP_TRACE_DEFAULT_VERBOSITY) if (code <= QDF_DP_TRACE_BASE_VERBOSITY)
return true; return true;
return false; return false;
default: default:
@@ -905,6 +928,9 @@ void qdf_dp_trace_set_track(qdf_nbuf_t nbuf, enum qdf_proto_dir dir)
{ {
uint32_t count = 0; uint32_t count = 0;
if (!g_qdf_dp_trace_data.enable)
return;
spin_lock_bh(&l_dp_trace_lock); spin_lock_bh(&l_dp_trace_lock);
if (QDF_TX == dir) if (QDF_TX == dir)
count = ++g_qdf_dp_trace_data.tx_count; count = ++g_qdf_dp_trace_data.tx_count;
@@ -933,7 +959,7 @@ EXPORT_SYMBOL(qdf_dp_trace_set_track);
* *
* Return: None * Return: None
*/ */
static void dump_hex_trace(char *str, uint8_t *buf, uint8_t buf_len) static void dump_dp_hex_trace(char *str, uint8_t *buf, uint8_t buf_len)
{ {
unsigned char linebuf[BUFFER_SIZE]; unsigned char linebuf[BUFFER_SIZE];
const u8 *ptr = buf; const u8 *ptr = buf;
@@ -947,7 +973,7 @@ static void dump_hex_trace(char *str, uint8_t *buf, uint8_t buf_len)
hex_dump_to_buffer(ptr + i, linelen, ROW_SIZE, 1, hex_dump_to_buffer(ptr + i, linelen, ROW_SIZE, 1,
linebuf, sizeof(linebuf), false); linebuf, sizeof(linebuf), false);
DPTRACE_PRINT("DPT: %s: %s", str, linebuf); DPTRACE_PRINT("DPT: %s %s", str, linebuf);
} }
} }
@@ -1088,27 +1114,27 @@ static const char *qdf_dp_subtype_to_str(enum qdf_proto_subtype subtype)
case QDF_PROTO_EAPOL_M4: case QDF_PROTO_EAPOL_M4:
return "M4"; return "M4";
case QDF_PROTO_DHCP_DISCOVER: case QDF_PROTO_DHCP_DISCOVER:
return "DISCOVER"; return "DISC";
case QDF_PROTO_DHCP_REQUEST: case QDF_PROTO_DHCP_REQUEST:
return "REQUEST"; return "REQ";
case QDF_PROTO_DHCP_OFFER: case QDF_PROTO_DHCP_OFFER:
return "OFFER"; return "OFF";
case QDF_PROTO_DHCP_ACK: case QDF_PROTO_DHCP_ACK:
return "ACK"; return "ACK";
case QDF_PROTO_DHCP_NACK: case QDF_PROTO_DHCP_NACK:
return "NACK"; return "NACK";
case QDF_PROTO_DHCP_RELEASE: case QDF_PROTO_DHCP_RELEASE:
return "RELEASE"; return "REL";
case QDF_PROTO_DHCP_INFORM: case QDF_PROTO_DHCP_INFORM:
return "INFORM"; return "INFORM";
case QDF_PROTO_DHCP_DECLINE: case QDF_PROTO_DHCP_DECLINE:
return "DECLINE"; return "DECL";
case QDF_PROTO_ARP_REQ: case QDF_PROTO_ARP_REQ:
case QDF_PROTO_ICMP_REQ: case QDF_PROTO_ICMP_REQ:
return "REQUEST"; return "REQ";
case QDF_PROTO_ARP_RES: case QDF_PROTO_ARP_RES:
case QDF_PROTO_ICMP_RES: case QDF_PROTO_ICMP_RES:
return "RESPONSE"; return "RSP";
case QDF_PROTO_MGMT_ASSOC: case QDF_PROTO_MGMT_ASSOC:
return "ASSOC"; return "ASSOC";
case QDF_PROTO_MGMT_DISASSOC: case QDF_PROTO_MGMT_DISASSOC:
@@ -1120,7 +1146,7 @@ static const char *qdf_dp_subtype_to_str(enum qdf_proto_subtype subtype)
case QDF_ROAM_SYNCH: case QDF_ROAM_SYNCH:
return "ROAM SYNCH"; return "ROAM SYNCH";
case QDF_ROAM_COMPLETE: case QDF_ROAM_COMPLETE:
return "ROAM COMPLETE"; return "ROAM COMP";
case QDF_ROAM_EVENTID: case QDF_ROAM_EVENTID:
return "ROAM EVENTID"; return "ROAM EVENTID";
default: default:
@@ -1213,12 +1239,75 @@ static void qdf_dp_add_record(enum QDF_DP_TRACE_ID code, uint8_t *data,
rec->pid = (in_interrupt() ? 0 : current->pid); rec->pid = (in_interrupt() ? 0 : current->pid);
spin_unlock_bh(&l_dp_trace_lock); spin_unlock_bh(&l_dp_trace_lock);
if ((g_qdf_dp_trace_data.live_mode || (print == true)) &&
(rec->code < QDF_DP_TRACE_MAX)) if (rec->code >= QDF_DP_TRACE_MAX) {
qdf_dp_trace_cb_table[rec->code] (rec, index, QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
QDF_TRACE_DEFAULT_PDEV_ID); "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);
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))
g_qdf_dp_trace_data.live_mode = 0;
spin_unlock_bh(&l_dp_trace_lock);
}
if (g_qdf_dp_trace_data.live_mode == true) {
qdf_dp_trace_cb_table[rec->code] (rec, index,
QDF_TRACE_DEFAULT_PDEV_ID, true);
return;
}
}
/**
* qdf_log_icmp_pkt() - log ICMP packet
* @session_id: vdev_id
* @skb: skb pointer
* @dir: direction
*
* Return: true/false
*/
static bool qdf_log_icmp_pkt(uint8_t session_id, struct sk_buff *skb,
enum qdf_proto_dir dir, uint8_t pdev_id)
{
enum qdf_proto_subtype proto_subtype;
if ((qdf_dp_get_proto_bitmap() & QDF_NBUF_PKT_TRAC_TYPE_ICMP) &&
(qdf_nbuf_is_icmp_pkt(skb) == true)) {
proto_subtype = qdf_nbuf_get_icmp_subtype(skb);
DPTRACE(qdf_dp_trace_proto_pkt(QDF_DP_TRACE_ICMP_PACKET_RECORD,
session_id, (skb->data + QDF_NBUF_SRC_MAC_OFFSET),
(skb->data + QDF_NBUF_DEST_MAC_OFFSET),
QDF_PROTO_TYPE_ICMP, proto_subtype, dir, pdev_id, false));
if (QDF_TX == dir)
QDF_NBUF_CB_TX_DP_TRACE(skb) = 1;
else if (QDF_RX == dir)
QDF_NBUF_CB_RX_DP_TRACE(skb) = 1;
QDF_NBUF_CB_DP_TRACE_PRINT(skb) = false;
if (proto_subtype == QDF_PROTO_ICMP_REQ)
g_qdf_dp_trace_data.icmp_req++;
else
g_qdf_dp_trace_data.icmp_resp++;
return true;
}
return false;
}
/** /**
* qdf_log_eapol_pkt() - log EAPOL packet * qdf_log_eapol_pkt() - log EAPOL packet
@@ -1243,7 +1332,7 @@ static bool qdf_log_eapol_pkt(uint8_t session_id, struct sk_buff *skb,
DPTRACE(qdf_dp_trace_proto_pkt(QDF_DP_TRACE_EAPOL_PACKET_RECORD, DPTRACE(qdf_dp_trace_proto_pkt(QDF_DP_TRACE_EAPOL_PACKET_RECORD,
session_id, (skb->data + QDF_NBUF_SRC_MAC_OFFSET), session_id, (skb->data + QDF_NBUF_SRC_MAC_OFFSET),
(skb->data + QDF_NBUF_DEST_MAC_OFFSET), (skb->data + QDF_NBUF_DEST_MAC_OFFSET),
QDF_PROTO_TYPE_EAPOL, subtype, dir, pdev_id)); QDF_PROTO_TYPE_EAPOL, subtype, dir, pdev_id, true));
if (QDF_TX == dir) if (QDF_TX == dir)
QDF_NBUF_CB_TX_DP_TRACE(skb) = 1; QDF_NBUF_CB_TX_DP_TRACE(skb) = 1;
else if (QDF_RX == dir) else if (QDF_RX == dir)
@@ -1278,7 +1367,8 @@ static bool qdf_log_dhcp_pkt(uint8_t session_id, struct sk_buff *skb,
DPTRACE(qdf_dp_trace_proto_pkt(QDF_DP_TRACE_DHCP_PACKET_RECORD, DPTRACE(qdf_dp_trace_proto_pkt(QDF_DP_TRACE_DHCP_PACKET_RECORD,
session_id, (skb->data + QDF_NBUF_SRC_MAC_OFFSET), session_id, (skb->data + QDF_NBUF_SRC_MAC_OFFSET),
(skb->data + QDF_NBUF_DEST_MAC_OFFSET), (skb->data + QDF_NBUF_DEST_MAC_OFFSET),
QDF_PROTO_TYPE_DHCP, subtype, dir, pdev_id)); QDF_PROTO_TYPE_DHCP, subtype, dir, pdev_id, true));
if (QDF_TX == dir) if (QDF_TX == dir)
QDF_NBUF_CB_TX_DP_TRACE(skb) = 1; QDF_NBUF_CB_TX_DP_TRACE(skb) = 1;
else if (QDF_RX == dir) else if (QDF_RX == dir)
@@ -1313,51 +1403,24 @@ static bool qdf_log_arp_pkt(uint8_t session_id, struct sk_buff *skb,
DPTRACE(qdf_dp_trace_proto_pkt(QDF_DP_TRACE_ARP_PACKET_RECORD, DPTRACE(qdf_dp_trace_proto_pkt(QDF_DP_TRACE_ARP_PACKET_RECORD,
session_id, (skb->data + QDF_NBUF_SRC_MAC_OFFSET), session_id, (skb->data + QDF_NBUF_SRC_MAC_OFFSET),
(skb->data + QDF_NBUF_DEST_MAC_OFFSET), (skb->data + QDF_NBUF_DEST_MAC_OFFSET),
QDF_PROTO_TYPE_ARP, proto_subtype, dir, pdev_id)); QDF_PROTO_TYPE_ARP, proto_subtype, dir, pdev_id, true));
if (QDF_TX == dir) if (QDF_TX == dir)
QDF_NBUF_CB_TX_DP_TRACE(skb) = 1; QDF_NBUF_CB_TX_DP_TRACE(skb) = 1;
else if (QDF_RX == dir) else if (QDF_RX == dir)
QDF_NBUF_CB_RX_DP_TRACE(skb) = 1; QDF_NBUF_CB_RX_DP_TRACE(skb) = 1;
QDF_NBUF_CB_DP_TRACE_PRINT(skb) = true; QDF_NBUF_CB_DP_TRACE_PRINT(skb) = true;
if (QDF_PROTO_ARP_REQ == proto_subtype)
g_qdf_dp_trace_data.arp_req++;
else
g_qdf_dp_trace_data.arp_resp++;
return true; return true;
} }
return false; return false;
} }
/**
* qdf_log_icmp_pkt() - log ICMP packet
* @session_id: vdev_id
* @skb: skb pointer
* @dir: direction
*
* Return: true/false
*/
static bool qdf_log_icmp_pkt(uint8_t session_id, struct sk_buff *skb,
enum qdf_proto_dir dir, uint8_t pdev_id)
{
enum qdf_proto_subtype proto_subtype;
if ((qdf_dp_get_proto_bitmap() & QDF_NBUF_PKT_TRAC_TYPE_ICMP) &&
(qdf_nbuf_is_icmp_pkt(skb) == true)) {
proto_subtype = qdf_nbuf_get_icmp_subtype(skb);
DPTRACE(qdf_dp_trace_proto_pkt(QDF_DP_TRACE_ICMP_PACKET_RECORD,
session_id, (skb->data + QDF_NBUF_SRC_MAC_OFFSET),
(skb->data + QDF_NBUF_DEST_MAC_OFFSET),
QDF_PROTO_TYPE_ICMP, proto_subtype, dir, pdev_id));
if (QDF_TX == dir)
QDF_NBUF_CB_TX_DP_TRACE(skb) = 1;
else if (QDF_RX == dir)
QDF_NBUF_CB_RX_DP_TRACE(skb) = 1;
QDF_NBUF_CB_DP_TRACE_PRINT(skb) = true;
return true;
}
return false;
}
/** /**
* qdf_dp_trace_log_pkt() - log packet type enabled through iwpriv * qdf_dp_trace_log_pkt() - log packet type enabled through iwpriv
@@ -1366,22 +1429,22 @@ static bool qdf_log_icmp_pkt(uint8_t session_id, struct sk_buff *skb,
* @dir: direction * @dir: direction
* @pdev_id: pdev_id * @pdev_id: pdev_id
* *
* Return: none * Return: true: some protocol was logged, false: no protocol was logged.
*/ */
void qdf_dp_trace_log_pkt(uint8_t session_id, struct sk_buff *skb, bool qdf_dp_trace_log_pkt(uint8_t session_id, struct sk_buff *skb,
enum qdf_proto_dir dir, uint8_t pdev_id) enum qdf_proto_dir dir, uint8_t pdev_id)
{ {
if (!qdf_dp_get_proto_bitmap()) if (!qdf_dp_get_proto_bitmap())
return; return false;
if (qdf_log_arp_pkt(session_id, skb, dir, pdev_id)) if (qdf_log_arp_pkt(session_id, skb, dir, pdev_id))
return; return true;
if (qdf_log_dhcp_pkt(session_id, skb, dir, pdev_id)) if (qdf_log_dhcp_pkt(session_id, skb, dir, pdev_id))
return; return true;
if (qdf_log_eapol_pkt(session_id, skb, dir, pdev_id)) if (qdf_log_eapol_pkt(session_id, skb, dir, pdev_id))
return; return true;
if (qdf_log_icmp_pkt(session_id, skb, dir, pdev_id)) if (qdf_log_icmp_pkt(session_id, skb, dir, pdev_id))
return; return true;
return false;
} }
EXPORT_SYMBOL(qdf_dp_trace_log_pkt); EXPORT_SYMBOL(qdf_dp_trace_log_pkt);
@@ -1389,19 +1452,22 @@ EXPORT_SYMBOL(qdf_dp_trace_log_pkt);
* qdf_dp_display_mgmt_pkt() - display proto packet * qdf_dp_display_mgmt_pkt() - display proto packet
* @record: dptrace record * @record: dptrace record
* @index: index * @index: index
* @live : live mode or dump mode
* *
* Return: none * Return: none
*/ */
void qdf_dp_display_mgmt_pkt(struct qdf_dp_trace_record_s *record, void qdf_dp_display_mgmt_pkt(struct qdf_dp_trace_record_s *record,
uint16_t index, uint8_t pdev_id) uint16_t index, uint8_t pdev_id, bool live)
{ {
struct qdf_dp_trace_mgmt_buf *buf = struct qdf_dp_trace_mgmt_buf *buf =
(struct qdf_dp_trace_mgmt_buf *)record->data; (struct qdf_dp_trace_mgmt_buf *)record->data;
DPTRACE_PRINT("DPT: %04d: %s: %s vdev_id %d", index, DPTRACE_PRINT("DPT: %04d: %s [%d] [%s %s %s]",
record->time, qdf_dp_code_to_string(record->code), index,
buf->vdev_id); (live == true) ? " " : record->time,
DPTRACE_PRINT("DPT: Type %s Subtype %s", qdf_dp_type_to_str(buf->type), 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_dp_subtype_to_str(buf->subtype));
} }
EXPORT_SYMBOL(qdf_dp_display_mgmt_pkt); EXPORT_SYMBOL(qdf_dp_display_mgmt_pkt);
@@ -1440,19 +1506,22 @@ EXPORT_SYMBOL(qdf_dp_trace_mgmt_pkt);
* qdf_dp_display_event_record() - display event records * qdf_dp_display_event_record() - display event records
* @record: dptrace record * @record: dptrace record
* @index: index * @index: index
* @live : live mode or dump mode
* *
* Return: none * Return: none
*/ */
void qdf_dp_display_event_record(struct qdf_dp_trace_record_s *record, void qdf_dp_display_event_record(struct qdf_dp_trace_record_s *record,
uint16_t index, uint8_t pdev_id) uint16_t index, uint8_t pdev_id, bool live)
{ {
struct qdf_dp_trace_event_buf *buf = struct qdf_dp_trace_event_buf *buf =
(struct qdf_dp_trace_event_buf *)record->data; (struct qdf_dp_trace_event_buf *)record->data;
DPTRACE_PRINT("DPT: %04d: %s: %s vdev_id %d", index, DPTRACE_PRINT("DPT: %04d: %s [%d] [%s %s %s]",
record->time, qdf_dp_code_to_string(record->code), index,
buf->vdev_id); (live == true) ? "" : record->time,
DPTRACE_PRINT("DPT: Type %s Subtype %s", qdf_dp_type_to_str(buf->type), 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_dp_subtype_to_str(buf->subtype));
} }
EXPORT_SYMBOL(qdf_dp_display_event_record); EXPORT_SYMBOL(qdf_dp_display_event_record);
@@ -1491,24 +1560,26 @@ EXPORT_SYMBOL(qdf_dp_trace_record_event);
* qdf_dp_display_proto_pkt() - display proto packet * qdf_dp_display_proto_pkt() - display proto packet
* @record: dptrace record * @record: dptrace record
* @index: index * @index: index
* @live : live mode or dump mode
* *
* Return: none * Return: none
*/ */
void qdf_dp_display_proto_pkt(struct qdf_dp_trace_record_s *record, void qdf_dp_display_proto_pkt(struct qdf_dp_trace_record_s *record,
uint16_t index, uint8_t pdev_id) uint16_t index, uint8_t pdev_id, bool live)
{ {
struct qdf_dp_trace_proto_buf *buf = struct qdf_dp_trace_proto_buf *buf =
(struct qdf_dp_trace_proto_buf *)record->data; (struct qdf_dp_trace_proto_buf *)record->data;
DPTRACE_PRINT("DPT: %04d: %s: %s vdev_id %d", index, DPTRACE_PRINT("DPT: %04d: %s [%d] [%s%s] SA: "
record->time, qdf_dp_code_to_string(record->code), QDF_MAC_ADDRESS_STR " %s DA: "
buf->vdev_id); QDF_MAC_ADDRESS_STR,
DPTRACE_PRINT("DPT: SA: " QDF_MAC_ADDRESS_STR " %s DA: " index,
QDF_MAC_ADDRESS_STR " Type %s Subtype %s", (live == true) ? "" : record->time,
QDF_MAC_ADDR_ARRAY(buf->sa.bytes), qdf_dp_dir_to_str(buf->dir), buf->vdev_id,
QDF_MAC_ADDR_ARRAY(buf->da.bytes), qdf_dp_code_to_string(record->code),
qdf_dp_type_to_str(buf->type), qdf_dp_subtype_to_str(buf->subtype),
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));
} }
EXPORT_SYMBOL(qdf_dp_display_proto_pkt); EXPORT_SYMBOL(qdf_dp_display_proto_pkt);
@@ -1522,13 +1593,14 @@ EXPORT_SYMBOL(qdf_dp_display_proto_pkt);
* @subtype: proto subtype * @subtype: proto subtype
* @dir: direction * @dir: direction
* @pdev_id: pdev id * @pdev_id: pdev id
* @print: to print this proto pkt or not
* *
* Return: none * Return: none
*/ */
void qdf_dp_trace_proto_pkt(enum QDF_DP_TRACE_ID code, uint8_t vdev_id, 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, uint8_t *sa, uint8_t *da, enum qdf_proto_type type,
enum qdf_proto_subtype subtype, enum qdf_proto_dir dir, enum qdf_proto_subtype subtype, enum qdf_proto_dir dir,
uint8_t pdev_id) uint8_t pdev_id, bool print)
{ {
struct qdf_dp_trace_proto_buf buf; struct qdf_dp_trace_proto_buf buf;
int buf_size = sizeof(struct qdf_dp_trace_ptr_buf); int buf_size = sizeof(struct qdf_dp_trace_ptr_buf);
@@ -1545,7 +1617,7 @@ void qdf_dp_trace_proto_pkt(enum QDF_DP_TRACE_ID code, uint8_t vdev_id,
buf.type = type; buf.type = type;
buf.subtype = subtype; buf.subtype = subtype;
buf.vdev_id = vdev_id; buf.vdev_id = vdev_id;
qdf_dp_add_record(code, (uint8_t *)&buf, buf_size, pdev_id, true); qdf_dp_add_record(code, (uint8_t *)&buf, buf_size, pdev_id, print);
} }
EXPORT_SYMBOL(qdf_dp_trace_proto_pkt); EXPORT_SYMBOL(qdf_dp_trace_proto_pkt);
@@ -1553,26 +1625,33 @@ EXPORT_SYMBOL(qdf_dp_trace_proto_pkt);
* qdf_dp_display_ptr_record() - display record * qdf_dp_display_ptr_record() - display record
* @record: dptrace record * @record: dptrace record
* @index: index * @index: index
* @live : live mode or dump mode
* *
* Return: none * Return: none
*/ */
void qdf_dp_display_ptr_record(struct qdf_dp_trace_record_s *record, void qdf_dp_display_ptr_record(struct qdf_dp_trace_record_s *record,
uint16_t index, uint8_t pdev_id) uint16_t index, uint8_t pdev_id, bool live)
{ {
char prepend_str[100] = {'\0'};
struct qdf_dp_trace_ptr_buf *buf = struct qdf_dp_trace_ptr_buf *buf =
(struct qdf_dp_trace_ptr_buf *)record->data; (struct qdf_dp_trace_ptr_buf *)record->data;
if (record->code == QDF_DP_TRACE_FREE_PACKET_PTR_RECORD) snprintf(prepend_str, sizeof(prepend_str),
DPTRACE_PRINT("DPT: %04d: %s: %s msdu_id: %d, status: %d", "%04d: %s [%s] [msdu id %d %s %d]",
index, record->time,
qdf_dp_code_to_string(record->code), buf->msdu_id,
buf->status);
else
DPTRACE_PRINT("DPT: %04d: %s: %s msdu_id: %d, vdev_id: %d",
index, index,
record->time, qdf_dp_code_to_string(record->code), (live == true) ? "" : record->time,
buf->msdu_id, buf->status); qdf_dp_code_to_string(record->code), buf->msdu_id,
dump_hex_trace("cookie", (uint8_t *)&buf->cookie, sizeof(buf->cookie)); (record->code == QDF_DP_TRACE_FREE_PACKET_PTR_RECORD) ?
"status" : "vdev_id",
buf->status);
if (live == true) {
/* In live mode donot dump the contents of the cookie */
DPTRACE_PRINT("DPT: %s", prepend_str);
} else {
dump_dp_hex_trace(prepend_str, (uint8_t *)&buf->cookie,
sizeof(buf->cookie));
}
} }
EXPORT_SYMBOL(qdf_dp_display_ptr_record); EXPORT_SYMBOL(qdf_dp_display_ptr_record);
@@ -1612,36 +1691,43 @@ EXPORT_SYMBOL(qdf_dp_trace_ptr);
* qdf_dp_display_trace() - Displays a record in DP trace * qdf_dp_display_trace() - Displays a record in DP trace
* @pRecord : pointer to a record in DP trace * @pRecord : pointer to a record in DP trace
* @recIndex : record index * @recIndex : record index
* @live : live mode or dump mode
* *
* Return: None * Return: None
*/ */
void qdf_dp_display_record(struct qdf_dp_trace_record_s *pRecord, void qdf_dp_display_record(struct qdf_dp_trace_record_s *pRecord,
uint16_t recIndex, uint8_t pdev_id) uint16_t recIndex, uint8_t pdev_id, bool live)
{
if (pdev_id == QDF_TRACE_DEFAULT_PDEV_ID ||
pdev_id == pRecord->pdev_id) {
DPTRACE_PRINT("DPT: %04d: PDEV_ID = %d: %s: %s", recIndex, {
pRecord->pdev_id, pRecord->time, char prepend_str[50] = {'\0'};
if (!(pdev_id == QDF_TRACE_DEFAULT_PDEV_ID ||
pdev_id == pRecord->pdev_id))
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_code_to_string(pRecord->code));
switch (pRecord->code) { switch (pRecord->code) {
case QDF_DP_TRACE_HDD_TX_TIMEOUT: case QDF_DP_TRACE_HDD_TX_TIMEOUT:
DPTRACE_PRINT("DPT: HDD TX Timeout\n"); DPTRACE_PRINT(" %s: HDD TX Timeout", prepend_str);
break; break;
case QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT: case QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT:
DPTRACE_PRINT("DPT: HDD SoftAP TX Timeout\n"); DPTRACE_PRINT(" %s: HDD SoftAP TX Timeout", prepend_str);
break; break;
case QDF_DP_TRACE_HDD_TX_PACKET_RECORD: case QDF_DP_TRACE_HDD_TX_PACKET_RECORD:
case QDF_DP_TRACE_HDD_RX_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_TX_PACKET_RECORD:
case QDF_DP_TRACE_LI_DP_RX_PACKET_RECORD: case QDF_DP_TRACE_LI_DP_RX_PACKET_RECORD:
case QDF_DP_TRACE_LI_DP_NULL_RX_PACKET_RECORD: case QDF_DP_TRACE_LI_DP_NULL_RX_PACKET_RECORD:
dump_hex_trace("DATA", pRecord->data, pRecord->size);
break;
default: default:
dump_hex_trace("cookie", pRecord->data, pRecord->size); dump_dp_hex_trace(prepend_str, pRecord->data, pRecord->size);
} break;
} };
} }
EXPORT_SYMBOL(qdf_dp_display_record); EXPORT_SYMBOL(qdf_dp_display_record);
@@ -1681,6 +1767,17 @@ void qdf_dp_trace_spin_lock_init(void)
} }
EXPORT_SYMBOL(qdf_dp_trace_spin_lock_init); EXPORT_SYMBOL(qdf_dp_trace_spin_lock_init);
/**
* qdf_dp_trace_disable_live_mode - disable live mode for dptrace
*
* Return: none
*/
void qdf_dp_trace_disable_live_mode(void)
{
g_qdf_dp_trace_data.live_mode = 0;
}
EXPORT_SYMBOL(qdf_dp_trace_disable_live_mode);
/** /**
* qdf_dp_trace_enable_live_mode() - enable live mode for dptrace * qdf_dp_trace_enable_live_mode() - enable live mode for dptrace
* *
@@ -1689,11 +1786,9 @@ EXPORT_SYMBOL(qdf_dp_trace_spin_lock_init);
void qdf_dp_trace_enable_live_mode(void) void qdf_dp_trace_enable_live_mode(void)
{ {
g_qdf_dp_trace_data.live_mode = 1; g_qdf_dp_trace_data.live_mode = 1;
} }
EXPORT_SYMBOL(qdf_dp_trace_enable_live_mode); EXPORT_SYMBOL(qdf_dp_trace_enable_live_mode);
/** /**
* qdf_dp_trace_clear_buffer() - clear dp trace buffer * qdf_dp_trace_clear_buffer() - clear dp trace buffer
* *
@@ -1704,18 +1799,6 @@ void qdf_dp_trace_clear_buffer(void)
g_qdf_dp_trace_data.head = INVALID_QDF_DP_TRACE_ADDR; g_qdf_dp_trace_data.head = INVALID_QDF_DP_TRACE_ADDR;
g_qdf_dp_trace_data.tail = INVALID_QDF_DP_TRACE_ADDR; g_qdf_dp_trace_data.tail = INVALID_QDF_DP_TRACE_ADDR;
g_qdf_dp_trace_data.num = 0; g_qdf_dp_trace_data.num = 0;
g_qdf_dp_trace_data.proto_bitmap = QDF_NBUF_PKT_TRAC_TYPE_EAPOL |
QDF_NBUF_PKT_TRAC_TYPE_DHCP |
QDF_NBUF_PKT_TRAC_TYPE_MGMT_ACTION |
QDF_NBUF_PKT_TRAC_TYPE_ARP |
QDF_NBUF_PKT_TRAC_TYPE_ICMP;
g_qdf_dp_trace_data.no_of_record = 0;
g_qdf_dp_trace_data.verbosity = QDF_DP_TRACE_VERBOSITY_HIGH;
g_qdf_dp_trace_data.enable = true;
g_qdf_dp_trace_data.tx_count = 0;
g_qdf_dp_trace_data.rx_count = 0;
g_qdf_dp_trace_data.live_mode = 0;
memset(g_qdf_dp_trace_tbl, 0, memset(g_qdf_dp_trace_tbl, 0,
MAX_QDF_DP_TRACE_RECORDS * sizeof(struct qdf_dp_trace_record_s)); MAX_QDF_DP_TRACE_RECORDS * sizeof(struct qdf_dp_trace_record_s));
} }
@@ -1739,7 +1822,24 @@ void qdf_dp_trace_dump_all(uint32_t count, uint8_t pdev_id)
return; return;
} }
DPTRACE_PRINT("Total Records: %d, Head: %d, Tail: %d", DPTRACE_PRINT(
"DPT: config - bitmap 0x%x verb %u #rec %u live_config %u thresh %u time_limit %u",
g_qdf_dp_trace_data.proto_bitmap,
g_qdf_dp_trace_data.verbosity,
g_qdf_dp_trace_data.no_of_record,
g_qdf_dp_trace_data.live_mode_config,
g_qdf_dp_trace_data.high_tput_thresh,
g_qdf_dp_trace_data.thresh_time_limit);
DPTRACE_PRINT("DPT: stats - tx %u rx %u icmp(%u %u) arp(%u %u)",
g_qdf_dp_trace_data.tx_count,
g_qdf_dp_trace_data.rx_count,
g_qdf_dp_trace_data.icmp_req,
g_qdf_dp_trace_data.icmp_resp,
g_qdf_dp_trace_data.arp_req,
g_qdf_dp_trace_data.arp_resp);
DPTRACE_PRINT("DPT: Total Records: %d, Head: %d, Tail: %d",
g_qdf_dp_trace_data.num, g_qdf_dp_trace_data.head, g_qdf_dp_trace_data.num, g_qdf_dp_trace_data.head,
g_qdf_dp_trace_data.tail); g_qdf_dp_trace_data.tail);
@@ -1765,9 +1865,8 @@ void qdf_dp_trace_dump_all(uint32_t count, uint8_t pdev_id)
p_record = g_qdf_dp_trace_tbl[i]; p_record = g_qdf_dp_trace_tbl[i];
spin_unlock_bh(&l_dp_trace_lock); spin_unlock_bh(&l_dp_trace_lock);
for (;; ) { for (;; ) {
qdf_dp_trace_cb_table[p_record.code](&p_record,
qdf_dp_trace_cb_table[p_record. (uint16_t)i, pdev_id, false);
code] (&p_record, (uint16_t)i, pdev_id);
if (i == tail) if (i == tail)
break; break;
i += 1; i += 1;
@@ -1992,6 +2091,53 @@ void qdf_trace_msg_cmn(unsigned int idx,
} }
EXPORT_SYMBOL(qdf_trace_msg_cmn); EXPORT_SYMBOL(qdf_trace_msg_cmn);
/**
* qdf_dp_trace_throttle_live_mode() - Throttle DP Trace live mode
* @high_bw_request: whether this is a high BW req or not
*
* The function tries to prevent excessive logging into the live buffer by
* having an upper limit on number of packets that can be logged per second.
*
* The intention is to allow occasional pings and data packets and really low
* throughput levels while suppressing bursts and higher throughput levels so
* that we donot hog the live buffer.
*
* If the number of packets printed in a particular second exceeds the thresh,
* disable printing in the next second.
*
* Return: None
*/
void qdf_dp_trace_throttle_live_mode(bool high_bw_request)
{
static int bw_interval_counter;
if (g_qdf_dp_trace_data.enable == false ||
g_qdf_dp_trace_data.live_mode_config == false)
return;
if (high_bw_request) {
g_qdf_dp_trace_data.live_mode = 0;
bw_interval_counter = 0;
return;
}
bw_interval_counter++;
if (0 == (bw_interval_counter %
g_qdf_dp_trace_data.thresh_time_limit)) {
spin_lock_bh(&l_dp_trace_lock);
if (g_qdf_dp_trace_data.print_pkt_cnt <=
g_qdf_dp_trace_data.high_tput_thresh)
g_qdf_dp_trace_data.live_mode = 1;
g_qdf_dp_trace_data.print_pkt_cnt = 0;
spin_unlock_bh(&l_dp_trace_lock);
}
}
EXPORT_SYMBOL(qdf_dp_trace_throttle_live_mode);
QDF_STATUS qdf_print_setup(void) QDF_STATUS qdf_print_setup(void)
{ {
int i; int i;