# # Copyright (c) 2014-2017 Qualcomm Atheros, Inc. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # # trace-cmd pktlog plugin for ath10k, QCA Linux wireless driver # # TODO: # # o create class for struct ieee80211_hdr each packet headers with # pack() and unpack() methods import struct import binascii DEBUG = 1 CUR_PKTLOG_VER = 10010 PKTLOG_MAGIC_NUM = 7735225 IEEE80211_FCTL_TODS = 0x0100 IEEE80211_FCTL_FROMDS = 0x0200 TARGET_NUM_MSDU_DESC = (1024 + 400) MAX_PKT_INFO_MSDU_ID = 192 MAX_10_4_PKT_INFO_MSDU_ID = 1 PKTLOG_MAX_TXCTL_WORDS = 57 # must match with enum ath10k_hw_rev from ath10k and existing values # should not change ATH10K_PKTLOG_HW_QCA988X = 0 ATH10K_PKTLOG_HW_QCA6174 = 1 ATH10K_PKTLOG_HW_QCA99X0 = 2 ATH10K_PKTLOG_HW_QCA9888 = 3 ATH10K_PKTLOG_HW_QCA9984 = 4 ATH10K_PKTLOG_HW_QCA9377 = 5 ATH10K_PKTLOG_HW_QCA40XX = 6 ATH10K_PKTLOG_HW_QCA9887 = 7 ATH10K_PKTLOG_TYPE_TX_CTRL = 1 ATH10K_PKTLOG_TYPE_TX_STAT = 2 ATH10K_PKTLOG_TYPE_TX_MSDU_ID = 3 ATH10K_PKTLOG_TYPE_TX_FRM_HDR = 4 ATH10K_PKTLOG_TYPE_RX_STAT = 5 ATH10K_PKTLOG_TYPE_RC_FIND = 6 ATH10K_PKTLOG_TYPE_RC_UPDATE = 7 ATH10K_PKTLOG_TYPE_TX_VIRT_ADDR = 8 ATH10K_PKTLOG_TYPE_DBG_PRINT = 9 ATH10K_PKTLOG_FLG_TYPE_LOCAL_S = 0 ATH10K_PKTLOG_FLG_TYPE_REMOTE_S = 1 ATH10K_PKTLOG_FLG_TYPE_CLONE_S = 2 ATH10K_PKTLOG_FLG_TYPE_UNKNOWN_S = 3 # sizeof(ath10k_pktlog_txctl) = 12 + 4 * 57 ATH10K_PKTLOG_TXCTL_LEN = 240 ATH10K_PKTLOG_MAX_TXCTL_WORDS = 57 # sizeof(ath10k_pktlog_10_4_txctl)2 = 16 + 4 * 153 ATH10K_PKTLOG_10_4_TXCTL_LEN = 624 ATH10K_PKTLOG_10_4_MAX_TXCTL_WORDS = 153 msdu_len_tbl = {} output_file = None frm_hdr = None def dbg(msg): if DEBUG == 0: return print(msg) def hexdump(buf, prefix=None): s = binascii.b2a_hex(buf) s_len = len(s) result = "" if prefix is None: prefix = "" for i in range(s_len / 2): if i % 16 == 0: result = result + ("%s%04x: " % (prefix, i)) result = result + (s[2 * i] + s[2 * i + 1] + " ") if (i + 1) % 16 == 0: result = result + "\n" # FIXME: if len(s) % 16 == 0 there's an extra \n in the end return result # struct ath10k_pktlog_hdr { # unsigned short flags; # unsigned short missed_cnt; # unsigned short log_type; # unsigned short size; # unsigned int timestamp; # unsigned char payload[0]; # } __attribute__((__packed__)); class Ath10kPktlogHdr: # 2 + 2 + 2 + 2 + 4 = 12 hdr_len = 12 struct_fmt = '= 4: txctl, = struct.unpack_from(' 0: num_msdu = num_msdu - 1 msdu_id, = struct.unpack_from(' TARGET_NUM_MSDU_DESC: dbg('Invalid msdu_id in tx: %d' % (msdu_id)) return msdu_len_tbl[msdu_id] = msdu_len def ath10k_txrx_tx_unref_handler(pevent, trace_seq, event): global msdu_len_tbl msdu_id = int(event['msdu_id']) trace_seq.puts('msdu_id %d\n' % (msdu_id)) if msdu_id > TARGET_NUM_MSDU_DESC: dbg('Invalid msdu_id from unref: %d' % (msdu_id)) return msdu_len_tbl[msdu_id] = 0 def ath10k_tx_hdr_handler(pevent, trace_seq, event): buf = event['data'].data pktlog_tx_frm_hdr(buf[0:]) def register(pevent): output_open() pevent.register_event_handler("ath10k", "ath10k_htt_pktlog", lambda *args: ath10k_htt_pktlog_handler(pevent, *args)) pevent.register_event_handler("ath10k", "ath10k_htt_rx_desc", lambda *args: ath10k_htt_rx_desc_handler(pevent, *args)) pevent.register_event_handler("ath10k", "ath10k_htt_tx", lambda *args: ath10k_htt_tx_handler(pevent, *args)) pevent.register_event_handler("ath10k", "ath10k_txrx_tx_unref", lambda *args: ath10k_txrx_tx_unref_handler(pevent, *args)) pevent.register_event_handler("ath10k", "ath10k_tx_hdr", lambda *args: ath10k_tx_hdr_handler(pevent, *args))