1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include "csr_wifi_hip_unifi.h"
16#include "unifi_priv.h"
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49static int
50unifi_mlme_wait_for_reply(unifi_priv_t *priv, ul_client_t *pcli, int sig_reply_id, int timeout)
51{
52 int retries = 0;
53 long r;
54 long t = timeout;
55 unsigned int sent_seq_no;
56
57
58 t = msecs_to_jiffies(t);
59
60 do {
61
62 r = wait_event_interruptible_timeout(pcli->udi_wq,
63 (pcli->wake_up_wq_id) || (priv->io_aborted == 1),
64 t);
65
66 if (priv->io_aborted) {
67 unifi_error(priv, "MLME operation aborted\n");
68 return -EIO;
69 }
70
71
72
73
74
75
76 if ((r == 0) && (pcli->wake_up_wq_id == 0)) {
77 unifi_error(priv, "mlme_wait: timed-out waiting for 0x%.4X, after %lu msec.\n",
78 sig_reply_id, jiffies_to_msecs(t));
79 pcli->wake_up_wq_id = 0;
80 return -ETIMEDOUT;
81 } else if (r == -ERESTARTSYS) {
82 unifi_error(priv, "mlme_wait: waiting for 0x%.4X was aborted.\n", sig_reply_id);
83 pcli->wake_up_wq_id = 0;
84 return -EINTR;
85 } else {
86
87 if (pcli->seq_no != 0) {
88 sent_seq_no = pcli->seq_no - 1;
89 } else {
90 sent_seq_no = 0x0F;
91 }
92
93 unifi_trace(priv, UDBG5, "Received 0x%.4X, seq: (r:%d, s:%d)\n",
94 pcli->wake_up_wq_id,
95 pcli->wake_seq_no, sent_seq_no);
96
97
98 if (pcli->wake_seq_no == sent_seq_no) {
99
100 if (sig_reply_id == pcli->wake_up_wq_id) {
101
102 break;
103 } else {
104
105 unifi_error(priv, "mlme_wait: mismatching signal id (0x%.4X - exp 0x%.4X) (seq %d)\n",
106 pcli->wake_up_wq_id,
107 sig_reply_id,
108 pcli->wake_seq_no);
109 pcli->wake_up_wq_id = 0;
110 return -EIO;
111 }
112 }
113
114 pcli->wake_up_wq_id = 0;
115
116 retries ++;
117 if (retries >= 3) {
118 unifi_error(priv, "mlme_wait: confirm wait retries exhausted (0x%.4X - exp 0x%.4X)\n",
119 pcli->wake_up_wq_id,
120 sig_reply_id);
121 pcli->wake_up_wq_id = 0;
122 return -EIO;
123 }
124 }
125 } while (1);
126
127 pcli->wake_up_wq_id = 0;
128
129 return 0;
130}
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150int
151unifi_mlme_blocking_request(unifi_priv_t *priv, ul_client_t *pcli,
152 CSR_SIGNAL *sig, bulk_data_param_t *data_ptrs,
153 int timeout)
154{
155 int r;
156
157 if (sig->SignalPrimitiveHeader.SignalId == 0) {
158 unifi_error(priv, "unifi_mlme_blocking_request: Invalid Signal Id (0x%x)\n",
159 sig->SignalPrimitiveHeader.SignalId);
160 return -EINVAL;
161 }
162
163 down(&priv->mlme_blocking_mutex);
164
165 sig->SignalPrimitiveHeader.ReceiverProcessId = 0;
166 sig->SignalPrimitiveHeader.SenderProcessId = pcli->sender_id | pcli->seq_no;
167
168 unifi_trace(priv, UDBG2, "Send client=%d, S:0x%04X, sig 0x%.4X\n",
169 pcli->client_id,
170 sig->SignalPrimitiveHeader.SenderProcessId,
171 sig->SignalPrimitiveHeader.SignalId);
172
173 r = ul_send_signal_unpacked(priv, sig, data_ptrs);
174 if (r) {
175 up(&priv->mlme_blocking_mutex);
176 unifi_error(priv, "Error queueing MLME REQUEST signal\n");
177 return r;
178 }
179
180 unifi_trace(priv, UDBG5, "Send 0x%.4X, seq = %d\n",
181 sig->SignalPrimitiveHeader.SignalId, pcli->seq_no);
182
183
184
185
186
187 pcli->seq_no++;
188 if (pcli->seq_no > 0x0F) {
189 pcli->seq_no = 0;
190 }
191
192 r = unifi_mlme_wait_for_reply(priv, pcli, (sig->SignalPrimitiveHeader.SignalId + 1), timeout);
193 up(&priv->mlme_blocking_mutex);
194
195 if (r) {
196 unifi_error(priv, "Error waiting for MLME CONFIRM signal\n");
197 return r;
198 }
199
200 return 0;
201}
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218void
219unifi_mlme_copy_reply_and_wakeup_client(ul_client_t *pcli,
220 CSR_SIGNAL *signal, int signal_len,
221 const bulk_data_param_t *bulkdata)
222{
223 int i;
224
225
226 memcpy(pcli->reply_signal, signal, signal_len);
227
228
229 pcli->wake_seq_no = pcli->reply_signal->SignalPrimitiveHeader.ReceiverProcessId & 0x0F;
230
231
232 for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
233 if (bulkdata->d[i].data_length > 0) {
234 if (bulkdata->d[i].os_data_ptr) {
235 memcpy(pcli->reply_bulkdata[i]->ptr, bulkdata->d[i].os_data_ptr, bulkdata->d[i].data_length);
236 pcli->reply_bulkdata[i]->length = bulkdata->d[i].data_length;
237 } else {
238 pcli->reply_bulkdata[i]->length = 0;
239 }
240 }
241 }
242
243
244 pcli->wake_up_wq_id = pcli->reply_signal->SignalPrimitiveHeader.SignalId;
245 wake_up_interruptible(&pcli->udi_wq);
246
247}
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264int
265uf_abort_mlme(unifi_priv_t *priv)
266{
267 ul_client_t *ul_cli;
268
269
270 priv->io_aborted = 1;
271
272 ul_cli = priv->netdev_client;
273 if (ul_cli) {
274 wake_up_interruptible(&ul_cli->udi_wq);
275 }
276
277 ul_cli = priv->wext_client;
278 if (ul_cli) {
279 wake_up_interruptible(&ul_cli->udi_wq);
280 }
281
282 return 0;
283}
284
285
286
287
288
289
290
291
292
293
294
295struct mlme_code {
296 const char *name;
297 int id;
298};
299
300static const struct mlme_code Result_codes[] = {
301 { "Success", 0x0000 },
302 { "Unspecified Failure", 0x0001 },
303
304 { "Refused Capabilities Mismatch", 0x000A },
305
306 { "Refused External Reason", 0x000C },
307
308 { "Refused AP Out Of Memory", 0x0011 },
309 { "Refused Basic Rates Mismatch", 0x0012 },
310
311 { "Failure", 0x0020 },
312
313 { "Refused Reason Unspecified", 0x0025 },
314 { "Invalid Parameters", 0x0026 },
315 { "Rejected With Suggested Changes", 0x0027 },
316
317 { "Rejected For Delay Period", 0x002F },
318 { "Not Allowed", 0x0030 },
319 { "Not Present", 0x0031 },
320 { "Not QSTA", 0x0032 },
321
322 { "Timeout", 0x8000 },
323 { "Too Many Simultaneous Requests", 0x8001 },
324 { "BSS Already Started Or Joined", 0x8002 },
325 { "Not Supported", 0x8003 },
326 { "Transmission Failure", 0x8004 },
327 { "Refused Not Authenticated", 0x8005 },
328 { "Reset Required Before Start", 0x8006 },
329 { "LM Info Unavailable", 0x8007 },
330 { NULL, -1 }
331};
332
333static const struct mlme_code Reason_codes[] = {
334
335 { "Unspecified Reason", 0x0001 },
336 { "Authentication Not Valid", 0x0002 },
337 { "Deauthenticated Leave BSS", 0x0003 },
338 { "Disassociated Inactivity", 0x0004 },
339 { "AP Overload", 0x0005 },
340 { "Class2 Frame Error", 0x0006 },
341 { "Class3 Frame Error", 0x0007 },
342 { "Disassociated Leave BSS", 0x0008 },
343 { "Association Not Authenticated", 0x0009 },
344 { "Disassociated Power Capability", 0x000A },
345 { "Disassociated Supported Channels", 0x000B },
346
347 { "Invalid Information Element", 0x000D },
348 { "Michael MIC Failure", 0x000E },
349 { "Fourway Handshake Timeout", 0x000F },
350 { "Group Key Update Timeout", 0x0010 },
351 { "Handshake Element Different", 0x0011 },
352 { "Invalid Group Cipher", 0x0012 },
353 { "Invalid Pairwise Cipher", 0x0013 },
354 { "Invalid AKMP", 0x0014 },
355 { "Unsupported RSN IE Version", 0x0015 },
356 { "Invalid RSN IE Capabilities", 0x0016 },
357 { "Dot1X Auth Failed", 0x0017 },
358 { "Cipher Rejected By Policy", 0x0018 },
359
360 { "QoS Unspecified Reason", 0x0020 },
361 { "QoS Insufficient Bandwidth", 0x0021 },
362 { "QoS Excessive Not Ack", 0x0022 },
363 { "QoS TXOP Limit Exceeded", 0x0023 },
364 { "QSTA Leaving", 0x0024 },
365 { "End TS, End DLS, End BA", 0x0025 },
366 { "Unknown TS, Unknown DLS, Unknown BA", 0x0026 },
367 { "Timeout", 0x0027 },
368
369 { "STAKey Mismatch", 0x002D },
370 { NULL, -1 }
371};
372
373
374static const char *
375lookup_something(const struct mlme_code *n, int id)
376{
377 for (; n->name; n++) {
378 if (n->id == id) {
379 return n->name;
380 }
381 }
382
383
384 return NULL;
385}
386
387
388const char *
389lookup_result_code(int result)
390{
391 static char fallback[16];
392 const char *str;
393
394 str = lookup_something(Result_codes, result);
395
396 if (str == NULL) {
397 snprintf(fallback, 16, "%d", result);
398 str = fallback;
399 }
400
401 return str;
402}
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418const char *
419lookup_reason_code(int reason)
420{
421 static char fallback[16];
422 const char *str;
423
424 str = lookup_something(Reason_codes, reason);
425
426 if (str == NULL) {
427 snprintf(fallback, 16, "%d", reason);
428 str = fallback;
429 }
430
431 return str;
432}
433
434