Merge branch 'omap-serial' of git://git.linaro.org/people/rmk/linux-arm
[firefly-linux-kernel-4.4.55.git] / drivers / staging / csr / csr_wifi_hip_udi.c
1 /*****************************************************************************
2
3             (c) Cambridge Silicon Radio Limited 2011
4             All rights reserved and confidential information of CSR
5
6             Refer to LICENSE.txt included with this source for details
7             on the license terms.
8
9 *****************************************************************************/
10
11 /*
12  * ---------------------------------------------------------------------------
13  *  FILE:     csr_wifi_hip_card_udi.c
14  *
15  *  PURPOSE:
16  *      Maintain a list of callbacks to log UniFi exchanges to one or more
17  *      debug/monitoring client applications.
18  *
19  * NOTES:
20  *      Just call the UDI driver log fn directly for now.
21  *      When done properly, each open() on the UDI device will install
22  *      a log function. We will call all log fns whenever a signal is written
23  *      to or read form the UniFi.
24  *
25  * ---------------------------------------------------------------------------
26  */
27 #include "csr_wifi_hip_unifi.h"
28 #include "csr_wifi_hip_card.h"
29
30
31 /*
32  * ---------------------------------------------------------------------------
33  *  unifi_print_status
34  *
35  *      Print status info to given character buffer.
36  *
37  *  Arguments:
38  *      None.
39  *
40  *  Returns:
41  *      None.
42  * ---------------------------------------------------------------------------
43  */
44 s32 unifi_print_status(card_t *card, char *str, s32 *remain)
45 {
46     char *p = str;
47     sdio_config_data_t *cfg;
48     u16 i, n;
49     s32 remaining = *remain;
50     s32 written;
51 #ifdef CSR_UNSAFE_SDIO_ACCESS
52     s32 iostate;
53     CsrResult r;
54     static const char *const states[] = {
55         "AWAKE", "DROWSY", "TORPID"
56     };
57     #define SHARED_READ_RETRY_LIMIT 10
58     u8 b;
59 #endif
60
61     if (remaining <= 0)
62     {
63         return 0;
64     }
65
66     i = n = 0;
67     written = scnprintf(p, remaining, "Chip ID %u\n",
68                           (u16)card->chip_id);
69     UNIFI_SNPRINTF_RET(p, remaining, written);
70     written = scnprintf(p, remaining, "Chip Version %04X\n",
71                           card->chip_version);
72     UNIFI_SNPRINTF_RET(p, remaining, written);
73     written = scnprintf(p, remaining, "HIP v%u.%u\n",
74                           (card->config_data.version >> 8) & 0xFF,
75                           card->config_data.version & 0xFF);
76     UNIFI_SNPRINTF_RET(p, remaining, written);
77     written = scnprintf(p, remaining, "Build %u: %s\n",
78                           card->build_id, card->build_id_string);
79     UNIFI_SNPRINTF_RET(p, remaining, written);
80
81     cfg = &card->config_data;
82
83     written = scnprintf(p, remaining, "sdio ctrl offset          %u\n",
84                           cfg->sdio_ctrl_offset);
85     UNIFI_SNPRINTF_RET(p, remaining, written);
86     written = scnprintf(p, remaining, "fromhost sigbuf handle    %u\n",
87                           cfg->fromhost_sigbuf_handle);
88     UNIFI_SNPRINTF_RET(p, remaining, written);
89     written = scnprintf(p, remaining, "tohost_sigbuf_handle      %u\n",
90                           cfg->tohost_sigbuf_handle);
91     UNIFI_SNPRINTF_RET(p, remaining, written);
92     written = scnprintf(p, remaining, "num_fromhost_sig_frags    %u\n",
93                           cfg->num_fromhost_sig_frags);
94     UNIFI_SNPRINTF_RET(p, remaining, written);
95     written = scnprintf(p, remaining, "num_tohost_sig_frags      %u\n",
96                           cfg->num_tohost_sig_frags);
97     UNIFI_SNPRINTF_RET(p, remaining, written);
98     written = scnprintf(p, remaining, "num_fromhost_data_slots   %u\n",
99                           cfg->num_fromhost_data_slots);
100     UNIFI_SNPRINTF_RET(p, remaining, written);
101     written = scnprintf(p, remaining, "num_tohost_data_slots     %u\n",
102                           cfg->num_tohost_data_slots);
103     UNIFI_SNPRINTF_RET(p, remaining, written);
104     written = scnprintf(p, remaining, "data_slot_size            %u\n",
105                           cfg->data_slot_size);
106     UNIFI_SNPRINTF_RET(p, remaining, written);
107
108     /* Added by protocol version 0x0001 */
109     written = scnprintf(p, remaining, "overlay_size              %u\n",
110                           (u16)cfg->overlay_size);
111     UNIFI_SNPRINTF_RET(p, remaining, written);
112
113     /* Added by protocol version 0x0300 */
114     written = scnprintf(p, remaining, "data_slot_round           %u\n",
115                           cfg->data_slot_round);
116     UNIFI_SNPRINTF_RET(p, remaining, written);
117     written = scnprintf(p, remaining, "sig_frag_size             %u\n",
118                           cfg->sig_frag_size);
119     UNIFI_SNPRINTF_RET(p, remaining, written);
120
121     /* Added by protocol version 0x0300 */
122     written = scnprintf(p, remaining, "tohost_sig_pad            %u\n",
123                           cfg->tohost_signal_padding);
124     UNIFI_SNPRINTF_RET(p, remaining, written);
125
126     written = scnprintf(p, remaining, "\nInternal state:\n");
127     UNIFI_SNPRINTF_RET(p, remaining, written);
128
129     written = scnprintf(p, remaining, "Last PHY PANIC: %04x:%04x\n",
130                           card->last_phy_panic_code, card->last_phy_panic_arg);
131     UNIFI_SNPRINTF_RET(p, remaining, written);
132     written = scnprintf(p, remaining, "Last MAC PANIC: %04x:%04x\n",
133                           card->last_mac_panic_code, card->last_mac_panic_arg);
134     UNIFI_SNPRINTF_RET(p, remaining, written);
135
136     written = scnprintf(p, remaining, "fhsr: %u\n",
137                           (u16)card->from_host_signals_r);
138     UNIFI_SNPRINTF_RET(p, remaining, written);
139     written = scnprintf(p, remaining, "fhsw: %u\n",
140                           (u16)card->from_host_signals_w);
141     UNIFI_SNPRINTF_RET(p, remaining, written);
142     written = scnprintf(p, remaining, "thsr: %u\n",
143                           (u16)card->to_host_signals_r);
144     UNIFI_SNPRINTF_RET(p, remaining, written);
145     written = scnprintf(p, remaining, "thsw: %u\n",
146                           (u16)card->to_host_signals_w);
147     UNIFI_SNPRINTF_RET(p, remaining, written);
148     written = scnprintf(p, remaining,
149                           "fh buffer contains: %d signals, %td bytes\n",
150                           card->fh_buffer.count,
151                           card->fh_buffer.ptr - card->fh_buffer.buf);
152     UNIFI_SNPRINTF_RET(p, remaining, written);
153
154     written = scnprintf(p, remaining, "paused: ");
155     UNIFI_SNPRINTF_RET(p, remaining, written);
156     for (i = 0; i < sizeof(card->tx_q_paused_flag) / sizeof(card->tx_q_paused_flag[0]); i++)
157     {
158         written = scnprintf(p, remaining, card->tx_q_paused_flag[i]?"1" : "0");
159         UNIFI_SNPRINTF_RET(p, remaining, written);
160     }
161     written = scnprintf(p, remaining, "\n");
162     UNIFI_SNPRINTF_RET(p, remaining, written);
163
164     written = scnprintf(p, remaining,
165                           "fh command q: %u waiting, %u free of %u:\n",
166                           CSR_WIFI_HIP_Q_SLOTS_USED(&card->fh_command_queue),
167                           CSR_WIFI_HIP_Q_SLOTS_FREE(&card->fh_command_queue),
168                           UNIFI_SOFT_COMMAND_Q_LENGTH);
169     UNIFI_SNPRINTF_RET(p, remaining, written);
170     for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
171     {
172         written = scnprintf(p, remaining,
173                               "fh traffic q[%u]: %u waiting, %u free of %u:\n",
174                               i,
175                               CSR_WIFI_HIP_Q_SLOTS_USED(&card->fh_traffic_queue[i]),
176                               CSR_WIFI_HIP_Q_SLOTS_FREE(&card->fh_traffic_queue[i]),
177                               UNIFI_SOFT_TRAFFIC_Q_LENGTH);
178         UNIFI_SNPRINTF_RET(p, remaining, written);
179     }
180
181     written = scnprintf(p, remaining, "fh data slots free: %u\n",
182                           card->from_host_data?CardGetFreeFromHostDataSlots(card) : 0);
183     UNIFI_SNPRINTF_RET(p, remaining, written);
184
185
186     written = scnprintf(p, remaining, "From host data slots:");
187     UNIFI_SNPRINTF_RET(p, remaining, written);
188     n = card->config_data.num_fromhost_data_slots;
189     for (i = 0; i < n && card->from_host_data; i++)
190     {
191         written = scnprintf(p, remaining, " %u",
192                               (u16)card->from_host_data[i].bd.data_length);
193         UNIFI_SNPRINTF_RET(p, remaining, written);
194     }
195     written = scnprintf(p, remaining, "\n");
196     UNIFI_SNPRINTF_RET(p, remaining, written);
197
198     written = scnprintf(p, remaining, "To host data slots:");
199     UNIFI_SNPRINTF_RET(p, remaining, written);
200     n = card->config_data.num_tohost_data_slots;
201     for (i = 0; i < n && card->to_host_data; i++)
202     {
203         written = scnprintf(p, remaining, " %u",
204                               (u16)card->to_host_data[i].data_length);
205         UNIFI_SNPRINTF_RET(p, remaining, written);
206     }
207
208     written = scnprintf(p, remaining, "\n");
209     UNIFI_SNPRINTF_RET(p, remaining, written);
210
211 #ifdef CSR_UNSAFE_SDIO_ACCESS
212     written = scnprintf(p, remaining, "Host State: %s\n", states[card->host_state]);
213     UNIFI_SNPRINTF_RET(p, remaining, written);
214
215     r = unifi_check_io_status(card, &iostate);
216     if (iostate == 1)
217     {
218         written = scnprintf(p, remaining, "I/O Check: F1 disabled\n");
219         UNIFI_SNPRINTF_RET(p, remaining, written);
220     }
221     else
222     {
223         if (iostate == 1)
224         {
225             written = scnprintf(p, remaining, "I/O Check: pending interrupt\n");
226             UNIFI_SNPRINTF_RET(p, remaining, written);
227         }
228
229         written = scnprintf(p, remaining, "BH reason interrupt = %d\n",
230                               card->bh_reason_unifi);
231         UNIFI_SNPRINTF_RET(p, remaining, written);
232         written = scnprintf(p, remaining, "BH reason host      = %d\n",
233                               card->bh_reason_host);
234         UNIFI_SNPRINTF_RET(p, remaining, written);
235
236         for (i = 0; i < SHARED_READ_RETRY_LIMIT; i++)
237         {
238             r = unifi_read_8_or_16(card, card->sdio_ctrl_addr + 2, &b);
239             if ((r == CSR_RESULT_SUCCESS) && (!(b & 0x80)))
240             {
241                 written = scnprintf(p, remaining, "fhsr: %u (driver thinks is %u)\n",
242                                       b, card->from_host_signals_r);
243                 UNIFI_SNPRINTF_RET(p, remaining, written);
244                 break;
245             }
246         }
247         iostate = unifi_read_shared_count(card, card->sdio_ctrl_addr + 4);
248         written = scnprintf(p, remaining, "thsw: %u (driver thinks is %u)\n",
249                               iostate, card->to_host_signals_w);
250         UNIFI_SNPRINTF_RET(p, remaining, written);
251     }
252 #endif
253
254     written = scnprintf(p, remaining, "\nStats:\n");
255     UNIFI_SNPRINTF_RET(p, remaining, written);
256     written = scnprintf(p, remaining, "Total SDIO bytes: R=%u W=%u\n",
257                           card->sdio_bytes_read, card->sdio_bytes_written);
258
259     UNIFI_SNPRINTF_RET(p, remaining, written);
260     written = scnprintf(p, remaining, "Interrupts generated on card: %u\n",
261                           card->unifi_interrupt_seq);
262     UNIFI_SNPRINTF_RET(p, remaining, written);
263
264     *remain = remaining;
265     return (p - str);
266 } /* unifi_print_status() */
267
268