/* Cesar project {{{ * * Copyright (C) 2007 Spidcom * * <<>> * * }}} */ /** * \file mac/pbproc/src/trace.c * \brief Define PBProc trace events. * \ingroup mac_pbproc */ #include "common/std.h" #include #include #include "mac/pbproc/inc/context.h" #include "inc/fc.h" /** * Format a FC. * \see trace_format_t. */ static int pbproc_trace_format_fc (char *text, uint text_size, const int *data, uint size) { static const char *mfs_cmd_str[] = { "INIT", "IN_SYNC", "RE_SYNC", "RELEASE", "NOP", "RES=5", "RES=6", "RES=7" }; static const char *mfs_rsp_str[] = { "ACK", "NACK", "FAIL", "HOLD" }; static const char *sackt[] = { "m", "mc", "nr", "u" }; char mrtfl[sizeof ("bbf mrtfl=0xn ")]; char mpdu_cnt[sizeof ("mpdu_cnt=n ")]; char burst_cnt[sizeof ("burst_cnt=n ")]; dbg_assert (size == 4); #define FC_ACCESS_SNID(fc) \ ((fc)->generic.access ? "A" : ""), ((fc)->generic.snid) int r; if (data[0] == -1) r = snprintf (text, text_size, "CRC ERROR"); else { const pbproc_fc_t *fc = (const void *) data; switch (fc->generic.dt_av) { case PBPROC_FC_DT_BEACON: r = snprintf (text, text_size, "BEACON snid=%s%d bts=0x%08x" " bto=%d,%d,%d,%d", FC_ACCESS_SNID (fc), fc->beacon.bts_lsb24 | fc->beacon.bts_msb8 << 24, fc->beacon.bto0, fc->beacon.bto1_lsb8 | fc->beacon.bto1_msb8 << 8, fc->beacon.bto2, fc->beacon.bto3_lsb8 | fc->beacon.bto3_msb8 << 8); break; case PBPROC_FC_DT_SOF: dbg_check (snprintf (mrtfl, sizeof (mrtfl), "bbf mrtfl=0x%x ", fc->sof.mrtfl) < (int) sizeof (mrtfl)); dbg_check (snprintf (mpdu_cnt, sizeof (mpdu_cnt), "mpdu_cnt=%d ", fc->sof.mpdu_cnt) < (int) sizeof (mpdu_cnt)); dbg_check (snprintf (burst_cnt, sizeof (burst_cnt), "burst_cnt=%d ", fc->sof.burst_cnt) < (int) sizeof (burst_cnt)); r = snprintf (text, text_size, "SOF snid=%s%d stei=0x%02x dtei=0x%02x lid=0x%02x" " %s%s%s%s%s%seks=%d ppb=0x%02x ble=0x%02x" " %snum_sym=%d tmi=%d fl_av=%d " "%s%s%s%s%s%smfs=m%s,%s,m%s,%s sacki=0x%x", FC_ACCESS_SNID (fc), fc->sof.stei, fc->sof.dtei, fc->sof.lid, fc->sof.mcf ? "mcf " : "", fc->sof.mnbf ? "mnbf " : "", fc->sof.cfs ? "cfs " : "", fc->sof.bdf ? "bdf " : "", fc->sof.hp10df ? "hp10df " : "", fc->sof.hp11df ? "hp11df " : "", fc->sof.eks, fc->sof.ppb, fc->sof.ble, fc->sof.pbsz ? "pb136 " : "", fc->sof.num_sym, fc->sof.tmi_av, fc->sof.fl_av, fc->sof.mpdu_cnt ? mpdu_cnt : "", fc->sof.burst_cnt ? burst_cnt : "", fc->sof.bbf ? mrtfl : "", fc->sof.dcppcf ? "dcppcf " : "", fc->sof.rsr ? "rsr " : "", fc->sof.clst ? "clst " : "", mfs_cmd_str[fc->sof.mfs_cmd_mgmt], mfs_cmd_str[fc->sof.mfs_cmd_data], mfs_rsp_str[fc->sof.mfs_rsp_mgmt], mfs_rsp_str[fc->sof.mfs_rsp_data], fc->sof.bm_sacki); break; case PBPROC_FC_DT_SACK: r = snprintf (text, text_size, "SACK snid=%s%d dtei=0x%02x %s%s%s%smfs=%s,m%s" " sackt=%s,%s,%s,%s sacki=0x%08x,0x%08x,0x%02x", FC_ACCESS_SNID (fc), fc->sack.dtei, fc->sack.cfs ? "cfs " : "", fc->sack.bdf ? "bdf " : "", fc->sack.svn ? "svn=1 " : "", fc->sack.rrtf ? "rrtf " : "", mfs_rsp_str[fc->sack.mfs_rsp_data], mfs_rsp_str[fc->sack.mfs_rsp_mgmt], sackt[fc->sack.sackt3], sackt[fc->sack.sackt2], sackt[fc->sack.sackt1], sackt[fc->sack.sackt0], fc->sack.sacki[0], fc->sack.sacki[1], fc->sack.sacki_last); break; case PBPROC_FC_DT_RTS_CTS: r = snprintf (text, text_size, "%s snid=%s%d stei=0x%02x dtei=0x%02x lid=0x%02x" " %s%s%s%s%s%s%sdur=%d", fc->rts_cts.rtsf ? "RTS" : "CTS", FC_ACCESS_SNID (fc), fc->rts_cts.stei, fc->rts_cts.dtei, fc->rts_cts.lid, fc->rts_cts.mcf ? "mcf " : "", fc->rts_cts.mnbf ? "mnbf " : "", fc->rts_cts.cfs ? "cfs " : "", fc->rts_cts.bdf ? "bdf " : "", fc->rts_cts.hp10df ? "hp10df " : "", fc->rts_cts.hp11df ? "hp11df " : "", fc->rts_cts.igf ? "igf " : "", fc->rts_cts.dur); break; case PBPROC_FC_DT_SOUND: dbg_check (snprintf (mpdu_cnt, sizeof (mpdu_cnt), "mpdu_cnt=%d ", fc->sound.mpdu_cnt) < (int) sizeof (mpdu_cnt)); r = snprintf (text, text_size, "SOUND snid=%s%d stei=0x%02x dtei=0x%02x lid=0x%02x" " %s%s%s%s%sreq_tm=%d fl_av=%d %sppb=0x%02x" " src=0x%02x", FC_ACCESS_SNID (fc), fc->sound.stei, fc->sound.dtei, fc->sound.lid, fc->sound.cfs ? "cfs " : "", fc->sound.pbsz ? "pb136 " : "", fc->sound.bdf ? "bdf " : "", fc->sound.saf ? "saf " : "", fc->sound.scf ? "scf " : "", fc->sound.req_tm, fc->sound.fl_av, fc->sound.mpdu_cnt ? mpdu_cnt : "", fc->sound.ppb, fc->sound.src); break; case PBPROC_FC_DT_RSOF: r = snprintf (text, text_size, "RSOF snid=%s%d dtei=0x%02x" " %s%s%s%smfs=m%s,%s,%s,m%s sackt=%s,%s,%s,%s" " sacki=0x%08x,0x%04x fl_av=%d tmi=%d %snum_sym=%d", FC_ACCESS_SNID (fc), fc->rsof.dtei, fc->rsof.cfs ? "cfs " : "", fc->rsof.bdf ? "bdf " : "", fc->rsof.svn ? "svn=1 " : "", fc->rsof.rrtf ? "rrtf " : "", mfs_cmd_str[fc->rsof.mfs_cmd_mgmt], mfs_cmd_str[fc->rsof.mfs_cmd_data], mfs_rsp_str[fc->rsof.mfs_rsp_data], mfs_rsp_str[fc->rsof.mfs_rsp_mgmt], sackt[fc->rsof.sackt3], sackt[fc->rsof.sackt2], sackt[fc->rsof.sackt1], sackt[fc->rsof.sackt0], fc->rsof.sacki_lsb, fc->rsof.sacki_msb, fc->rsof.rsof_fl_av <= 0x200 ? fc->rsof.rsof_fl_av : fc->rsof.rsof_fl_av * 2 - 0x200, fc->rsof.tmi_av, fc->rsof.pbsz ? "pb136 " : "", fc->rsof.num_sym); break; default: r = snprintf (text, text_size, "UNKNOWN dt=%d snid=%s%d", fc->generic.dt_av, FC_ACCESS_SNID (fc)); break; } } return r >= (int) text_size ? -1 : r; } /** * Format a FSM state. * \see trace_format_t. */ static int pbproc_trace_format_state (char *text, uint text_size, int data) { static const char *state_names[] = { "IDLE", "RX_DATA_WACK", "RX_DATA_WACK_LAST_PB", "RX_DATA_WOACK", "RX_BURST", "RX_BEACON", "RX_SOUND", "TX_WAIT_CTS", "TX_WAIT_ACCESS_CONF", "TX_WAIT_SACKD", "TX_WAIT_TX_END", "TX_BURST", "TX_SOUND_WAIT_ACK", }; const char *state_name; dbg_assert (COUNT (state_names) == PBPROC_FSM_STATE_NB); if (data < 0 || data >= PBPROC_FSM_STATE_NB) state_name = "UNKNOWN"; else state_name = state_names[data]; uint state_name_len = strlen (state_name); if (state_name_len > text_size) return -1; else { memcpy (text, state_name, state_name_len); return state_name_len; } } /** * Format a PBDMA status. * \see trace_format_t. */ static int pbproc_trace_format_pbdma_status (char *text, uint text_size, int data) { char *t = text; uint s = 0; phy_pbdma_status_t status = PHY_PBDMA_STATUS (data); if (status.pb_null) { int r = snprintf (t, text_size - s, "N%u", status.null_pb_index); if (r >= (int) (text_size - s)) return -1; s += r; t += r; } if (status.pb_crc_error) { s++; if (s > text_size) return -1; *t++ = '#'; } if (status.pb_it) { s++; if (s > text_size) return -1; *t++ = 'I'; } if (status.end_rx_pb) { s++; if (s > text_size) return -1; *t++ = 'R'; } if (status.end_tx_pb) { s++; if (s > text_size) return -1; *t++ = 'T'; } if (status.end_chandata) { s++; if (s > text_size) return -1; *t++ = 'C'; } if (status.rx_header_load_error || status.ahb_response_error || status.chandata_type_forbidden || status.chandata_size_forbidden || status.pb_nb_total_null) { s++; if (s > text_size) return -1; *t++ = 'X'; } return s; } void pbproc_trace_init (pbproc_t *ctx) { static trace_namespace_t namespace; static const trace_event_id_t event_ids[] = { TRACE_EVENT (PBPROC_TRACE_INIT, "init"), TRACE_EVENT (PBPROC_TRACE_UNINIT, "uninit"), TRACE_EVENT (PBPROC_TRACE_ACTIVATE, "activate %b", TIMESTAMP), TRACE_EVENT (PBPROC_TRACE_RX_SEG_REFILL, "rx seg refill %d"), TRACE_EVENT (PBPROC_TRACE_RX_CB, "rx cb pb_nb=%d"), TRACE_EVENT (PBPROC_TRACE_RX_BEACON_CB, "rx beacon cb"), TRACE_EVENT (PBPROC_TRACE_FSM_RX_FC, "fsm RX FC pre_date=%x %F", TIMESTAMP), TRACE_EVENT (PBPROC_TRACE_FSM_ACCESS, "fsm ACCESS", TIMESTAMP), TRACE_EVENT (PBPROC_TRACE_FSM_ACCESS_CONF, "fsm ACCESS CONF", TIMESTAMP), TRACE_EVENT (PBPROC_TRACE_FSM_PBDMA, "fsm PBDMA %P", TIMESTAMP), TRACE_EVENT (PBPROC_TRACE_FSM_DEFERRED, "fsm DEFERRED", TIMESTAMP), TRACE_EVENT (PBPROC_TRACE_FSM_CHANGE_STATE, "fsm change state %S"), TRACE_EVENT (PBPROC_TRACE_FSM_UNEXPECTED, "fsm unexpected"), TRACE_EVENT (PBPROC_TRACE_FTOP_AIFS, "ftop aifs"), TRACE_EVENT (PBPROC_TRACE_FTOP_PRP_LOST, "ftop prp lost"), TRACE_EVENT (PBPROC_TRACE_FTOP_TX, "ftop tx mfs=%x dtei=%d lid=%d " "tx_date=%x flp_tck=%d pb_nb=%d"), TRACE_EVENT (PBPROC_TRACE_FTOP_TX_INVALID, "ftop tx invalid"), TRACE_EVENT (PBPROC_TRACE_FRDA_SACK_UNIFORM, "frda sack uniform sacki=%d"), TRACE_EVENT (PBPROC_TRACE_FRDA_SACK_MIXED, "frda sack mixed"), TRACE_EVENT (PBPROC_TRACE_FRDA_SACK_MIXED_COMPRESSED, "frda sack mixed compressed"), TRACE_EVENT (PBPROC_TRACE_PREP_MPDU_COMMIT, "commit return_nb=%d"), }; dbg_assert (ctx); trace_namespace_init (&namespace, event_ids, COUNT (event_ids)); trace_namespace_register_format_table (&namespace, 'F', pbproc_trace_format_fc, 4); trace_namespace_register_format (&namespace, 'S', pbproc_trace_format_state); trace_namespace_register_format (&namespace, 'P', pbproc_trace_format_pbdma_status); trace_buffer_add (&ctx->trace, "pbproc", 8, 4, true, &namespace); } void pbproc_trace_uninit (pbproc_t *ctx) { dbg_assert (ctx); trace_buffer_remove (&ctx->trace); }