| /***************************************************************************** |
| |
| (c) Cambridge Silicon Radio Limited 2011 |
| All rights reserved and confidential information of CSR |
| |
| Refer to LICENSE.txt included with this source for details |
| on the license terms. |
| |
| *****************************************************************************/ |
| |
| /* |
| * --------------------------------------------------------------------------- |
| * FILE: csr_wifi_hip_card_udi.c |
| * |
| * PURPOSE: |
| * Maintain a list of callbacks to log UniFi exchanges to one or more |
| * debug/monitoring client applications. |
| * |
| * NOTES: |
| * Just call the UDI driver log fn directly for now. |
| * When done properly, each open() on the UDI device will install |
| * a log function. We will call all log fns whenever a signal is written |
| * to or read form the UniFi. |
| * |
| * --------------------------------------------------------------------------- |
| */ |
| #include "csr_wifi_hip_unifi.h" |
| #include "csr_wifi_hip_card.h" |
| |
| |
| /* |
| * --------------------------------------------------------------------------- |
| * unifi_print_status |
| * |
| * Print status info to given character buffer. |
| * |
| * Arguments: |
| * None. |
| * |
| * Returns: |
| * None. |
| * --------------------------------------------------------------------------- |
| */ |
| s32 unifi_print_status(card_t *card, char *str, s32 *remain) |
| { |
| char *p = str; |
| sdio_config_data_t *cfg; |
| u16 i, n; |
| s32 remaining = *remain; |
| s32 written; |
| #ifdef CSR_UNSAFE_SDIO_ACCESS |
| s32 iostate; |
| CsrResult r; |
| static const char *const states[] = { |
| "AWAKE", "DROWSY", "TORPID" |
| }; |
| #define SHARED_READ_RETRY_LIMIT 10 |
| u8 b; |
| #endif |
| |
| if (remaining <= 0) |
| { |
| return 0; |
| } |
| |
| i = n = 0; |
| written = scnprintf(p, remaining, "Chip ID %u\n", |
| (u16)card->chip_id); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| written = scnprintf(p, remaining, "Chip Version %04X\n", |
| card->chip_version); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| written = scnprintf(p, remaining, "HIP v%u.%u\n", |
| (card->config_data.version >> 8) & 0xFF, |
| card->config_data.version & 0xFF); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| written = scnprintf(p, remaining, "Build %u: %s\n", |
| card->build_id, card->build_id_string); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| |
| cfg = &card->config_data; |
| |
| written = scnprintf(p, remaining, "sdio ctrl offset %u\n", |
| cfg->sdio_ctrl_offset); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| written = scnprintf(p, remaining, "fromhost sigbuf handle %u\n", |
| cfg->fromhost_sigbuf_handle); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| written = scnprintf(p, remaining, "tohost_sigbuf_handle %u\n", |
| cfg->tohost_sigbuf_handle); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| written = scnprintf(p, remaining, "num_fromhost_sig_frags %u\n", |
| cfg->num_fromhost_sig_frags); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| written = scnprintf(p, remaining, "num_tohost_sig_frags %u\n", |
| cfg->num_tohost_sig_frags); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| written = scnprintf(p, remaining, "num_fromhost_data_slots %u\n", |
| cfg->num_fromhost_data_slots); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| written = scnprintf(p, remaining, "num_tohost_data_slots %u\n", |
| cfg->num_tohost_data_slots); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| written = scnprintf(p, remaining, "data_slot_size %u\n", |
| cfg->data_slot_size); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| |
| /* Added by protocol version 0x0001 */ |
| written = scnprintf(p, remaining, "overlay_size %u\n", |
| (u16)cfg->overlay_size); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| |
| /* Added by protocol version 0x0300 */ |
| written = scnprintf(p, remaining, "data_slot_round %u\n", |
| cfg->data_slot_round); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| written = scnprintf(p, remaining, "sig_frag_size %u\n", |
| cfg->sig_frag_size); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| |
| /* Added by protocol version 0x0300 */ |
| written = scnprintf(p, remaining, "tohost_sig_pad %u\n", |
| cfg->tohost_signal_padding); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| |
| written = scnprintf(p, remaining, "\nInternal state:\n"); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| |
| written = scnprintf(p, remaining, "Last PHY PANIC: %04x:%04x\n", |
| card->last_phy_panic_code, card->last_phy_panic_arg); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| written = scnprintf(p, remaining, "Last MAC PANIC: %04x:%04x\n", |
| card->last_mac_panic_code, card->last_mac_panic_arg); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| |
| written = scnprintf(p, remaining, "fhsr: %u\n", |
| (u16)card->from_host_signals_r); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| written = scnprintf(p, remaining, "fhsw: %u\n", |
| (u16)card->from_host_signals_w); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| written = scnprintf(p, remaining, "thsr: %u\n", |
| (u16)card->to_host_signals_r); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| written = scnprintf(p, remaining, "thsw: %u\n", |
| (u16)card->to_host_signals_w); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| written = scnprintf(p, remaining, |
| "fh buffer contains: %d signals, %td bytes\n", |
| card->fh_buffer.count, |
| card->fh_buffer.ptr - card->fh_buffer.buf); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| |
| written = scnprintf(p, remaining, "paused: "); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| for (i = 0; i < sizeof(card->tx_q_paused_flag) / sizeof(card->tx_q_paused_flag[0]); i++) |
| { |
| written = scnprintf(p, remaining, card->tx_q_paused_flag[i]?"1" : "0"); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| } |
| written = scnprintf(p, remaining, "\n"); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| |
| written = scnprintf(p, remaining, |
| "fh command q: %u waiting, %u free of %u:\n", |
| CSR_WIFI_HIP_Q_SLOTS_USED(&card->fh_command_queue), |
| CSR_WIFI_HIP_Q_SLOTS_FREE(&card->fh_command_queue), |
| UNIFI_SOFT_COMMAND_Q_LENGTH); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| for (i = 0; i < UNIFI_NO_OF_TX_QS; i++) |
| { |
| written = scnprintf(p, remaining, |
| "fh traffic q[%u]: %u waiting, %u free of %u:\n", |
| i, |
| CSR_WIFI_HIP_Q_SLOTS_USED(&card->fh_traffic_queue[i]), |
| CSR_WIFI_HIP_Q_SLOTS_FREE(&card->fh_traffic_queue[i]), |
| UNIFI_SOFT_TRAFFIC_Q_LENGTH); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| } |
| |
| written = scnprintf(p, remaining, "fh data slots free: %u\n", |
| card->from_host_data?CardGetFreeFromHostDataSlots(card) : 0); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| |
| |
| written = scnprintf(p, remaining, "From host data slots:"); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| n = card->config_data.num_fromhost_data_slots; |
| for (i = 0; i < n && card->from_host_data; i++) |
| { |
| written = scnprintf(p, remaining, " %u", |
| (u16)card->from_host_data[i].bd.data_length); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| } |
| written = scnprintf(p, remaining, "\n"); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| |
| written = scnprintf(p, remaining, "To host data slots:"); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| n = card->config_data.num_tohost_data_slots; |
| for (i = 0; i < n && card->to_host_data; i++) |
| { |
| written = scnprintf(p, remaining, " %u", |
| (u16)card->to_host_data[i].data_length); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| } |
| |
| written = scnprintf(p, remaining, "\n"); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| |
| #ifdef CSR_UNSAFE_SDIO_ACCESS |
| written = scnprintf(p, remaining, "Host State: %s\n", states[card->host_state]); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| |
| r = unifi_check_io_status(card, &iostate); |
| if (iostate == 1) |
| { |
| written = scnprintf(p, remaining, "I/O Check: F1 disabled\n"); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| } |
| else |
| { |
| if (iostate == 1) |
| { |
| written = scnprintf(p, remaining, "I/O Check: pending interrupt\n"); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| } |
| |
| written = scnprintf(p, remaining, "BH reason interrupt = %d\n", |
| card->bh_reason_unifi); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| written = scnprintf(p, remaining, "BH reason host = %d\n", |
| card->bh_reason_host); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| |
| for (i = 0; i < SHARED_READ_RETRY_LIMIT; i++) |
| { |
| r = unifi_read_8_or_16(card, card->sdio_ctrl_addr + 2, &b); |
| if ((r == CSR_RESULT_SUCCESS) && (!(b & 0x80))) |
| { |
| written = scnprintf(p, remaining, "fhsr: %u (driver thinks is %u)\n", |
| b, card->from_host_signals_r); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| break; |
| } |
| } |
| iostate = unifi_read_shared_count(card, card->sdio_ctrl_addr + 4); |
| written = scnprintf(p, remaining, "thsw: %u (driver thinks is %u)\n", |
| iostate, card->to_host_signals_w); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| } |
| #endif |
| |
| written = scnprintf(p, remaining, "\nStats:\n"); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| written = scnprintf(p, remaining, "Total SDIO bytes: R=%u W=%u\n", |
| card->sdio_bytes_read, card->sdio_bytes_written); |
| |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| written = scnprintf(p, remaining, "Interrupts generated on card: %u\n", |
| card->unifi_interrupt_seq); |
| UNIFI_SNPRINTF_RET(p, remaining, written); |
| |
| *remain = remaining; |
| return (p - str); |
| } /* unifi_print_status() */ |
| |
| |