1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include <linux/slab.h>
21#include "csr_wifi_hip_unifi.h"
22#include "csr_wifi_hip_unifiversion.h"
23#include "csr_wifi_hip_card.h"
24#include "csr_wifi_hip_xbv.h"
25
26#undef CSR_WIFI_IGNORE_PATCH_VERSION_MISMATCH
27
28static CsrResult do_patch_download(card_t *card, void *dlpriv,
29 xbv1_t *pfwinfo, u32 boot_ctrl_addr);
30
31static CsrResult do_patch_convert_download(card_t *card,
32 void *dlpriv, xbv1_t *pfwinfo);
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53static CsrResult _find_in_slut(card_t *card, symbol_t *psym, u32 *pslut)
54{
55 u32 slut_address;
56 u16 finger_print;
57 CsrResult r;
58 CsrResult csrResult;
59
60
61 if (*pslut == 0xffffffff)
62 {
63 r = card_wait_for_firmware_to_start(card, &slut_address);
64 if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
65 {
66 return r;
67 }
68 if (r != CSR_RESULT_SUCCESS)
69 {
70 unifi_error(card->ospriv, "Firmware hasn't started\n");
71 return r;
72 }
73 *pslut = slut_address;
74
75
76
77
78
79 csrResult = CsrSdioMaxBusClockFrequencySet(card->sdio_if, UNIFI_SDIO_CLOCK_INIT_HZ);
80 if (csrResult != CSR_RESULT_SUCCESS)
81 {
82 r = ConvertCsrSdioToCsrHipResult(card, csrResult);
83 return r;
84 }
85 card->sdio_clock_speed = UNIFI_SDIO_CLOCK_INIT_HZ;
86 }
87 else
88 {
89 slut_address = *pslut;
90 }
91 unifi_trace(card->ospriv, UDBG4, "SLUT addr: 0x%lX\n", slut_address);
92
93
94
95
96
97 unifi_trace(card->ospriv, UDBG4, "Looking for SLUT finger print\n");
98 finger_print = 0;
99 r = unifi_card_read16(card, slut_address, &finger_print);
100 if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
101 {
102 return r;
103 }
104 if (r != CSR_RESULT_SUCCESS)
105 {
106 unifi_error(card->ospriv, "Failed to read SLUT finger print\n");
107 return r;
108 }
109
110 if (finger_print != SLUT_FINGERPRINT)
111 {
112 unifi_error(card->ospriv, "Failed to find SLUT fingerprint\n");
113 return CSR_RESULT_FAILURE;
114 }
115
116
117 slut_address += 2;
118
119 while (1)
120 {
121 u16 id;
122 u32 obj;
123
124 r = unifi_card_read16(card, slut_address, &id);
125 if (r != CSR_RESULT_SUCCESS)
126 {
127 return r;
128 }
129 slut_address += 2;
130
131 if (id == CSR_SLT_END)
132 {
133
134 r = CSR_WIFI_HIP_RESULT_RANGE;
135 break;
136 }
137
138 r = unifi_read32(card, slut_address, &obj);
139 if (r != CSR_RESULT_SUCCESS)
140 {
141 return r;
142 }
143 slut_address += 4;
144
145 unifi_trace(card->ospriv, UDBG3, " found SLUT id %02d.%08lx\n", id, obj);
146
147 r = CSR_WIFI_HIP_RESULT_NOT_FOUND;
148
149 if (id == psym->id)
150 {
151 unifi_trace(card->ospriv, UDBG1, " matched SLUT id %02d.%08lx\n", id, obj);
152 psym->obj = obj;
153 r = CSR_RESULT_SUCCESS;
154 break;
155 }
156 }
157
158 return r;
159}
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180static CsrResult do_patch_convert_download(card_t *card, void *dlpriv, xbv1_t *pfwinfo)
181{
182 CsrResult r;
183 u32 slut_base = 0xffffffff;
184 void *pfw;
185 u32 psize;
186 symbol_t sym;
187
188
189 r = unifi_init(card);
190 if (r != CSR_RESULT_SUCCESS)
191 {
192 unifi_error(card->ospriv,
193 "do_patch_convert_download: failed to re-init UniFi\n");
194 return r;
195 }
196
197
198 if (card->build_id == 0)
199 {
200 u32 ver = 0;
201 sym.id = CSR_SLT_BUILD_ID_NUMBER;
202 sym.obj = 0;
203
204 unifi_trace(card->ospriv, UDBG1, "Need f/w version\n");
205
206
207 r = _find_in_slut(card, &sym, &slut_base);
208 if (r != CSR_RESULT_SUCCESS)
209 {
210 unifi_error(card->ospriv, "Failed to find CSR_SLT_BUILD_ID_NUMBER\n");
211 return CSR_RESULT_FAILURE;
212 }
213
214
215 r = unifi_read32(card, sym.obj, &ver);
216 if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
217 {
218 return r;
219 }
220 if (r != CSR_RESULT_SUCCESS)
221 {
222 unifi_error(card->ospriv, "Failed to read f/w id\n");
223 return CSR_RESULT_FAILURE;
224 }
225 card->build_id = ver;
226 }
227
228
229 pfw = xbv_to_patch(card, unifi_fw_read, dlpriv, pfwinfo, &psize);
230 if (!pfw)
231 {
232 unifi_error(card->ospriv, "Failed to convert f/w to patch");
233 return CSR_WIFI_HIP_RESULT_NO_MEMORY;
234 }
235 else
236 {
237 void *desc;
238 sym.id = CSR_SLT_BOOT_LOADER_CONTROL;
239 sym.obj = 0;
240
241
242 r = _find_in_slut(card, &sym, &slut_base);
243 if (r != CSR_RESULT_SUCCESS)
244 {
245 unifi_error(card->ospriv, "Failed to find BOOT_LOADER_CONTROL\n");
246 kfree(pfw);
247 return CSR_RESULT_FAILURE;
248 }
249
250 r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
251 if (r != CSR_RESULT_SUCCESS)
252 {
253 unifi_error(card->ospriv, "Failed to wake UniFi\n");
254 }
255
256
257
258
259 desc = unifi_fw_open_buffer(card->ospriv, pfw, psize);
260 if (!desc)
261 {
262 kfree(pfw);
263 return CSR_WIFI_HIP_RESULT_NO_MEMORY;
264 }
265
266
267 unifi_info(card->ospriv, "Downloading converted f/w as patch\n");
268 r = unifi_dl_patch(card, desc, sym.obj);
269 kfree(pfw);
270 unifi_fw_close_buffer(card->ospriv, desc);
271
272 if (r != CSR_RESULT_SUCCESS)
273 {
274 unifi_error(card->ospriv, "Converted patch download failed\n");
275 return r;
276 }
277 else
278 {
279 unifi_trace(card->ospriv, UDBG1, "Converted patch downloaded\n");
280 }
281
282
283 r = unifi_do_loader_op(card, sym.obj + 6, UNIFI_BOOT_LOADER_RESTART);
284 if (r != CSR_RESULT_SUCCESS)
285 {
286 unifi_error(card->ospriv, "Failed to write loader restart cmd\n");
287 }
288
289 return r;
290 }
291}
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316CsrResult unifi_dl_firmware(card_t *card, void *dlpriv)
317{
318 xbv1_t *fwinfo;
319 CsrResult r;
320
321 fwinfo = kmalloc(sizeof(xbv1_t), GFP_KERNEL);
322 if (fwinfo == NULL)
323 {
324 unifi_error(card->ospriv, "Failed to allocate memory for firmware\n");
325 return CSR_WIFI_HIP_RESULT_NO_MEMORY;
326 }
327
328
329
330
331
332
333
334
335
336
337 r = xbv1_parse(card, unifi_fw_read, dlpriv, fwinfo);
338 if (r != CSR_RESULT_SUCCESS || fwinfo->mode != xbv_firmware)
339 {
340 unifi_error(card->ospriv, "File type is %s, expected firmware.\n",
341 fwinfo->mode == xbv_patch?"patch" : "unknown");
342 kfree(fwinfo);
343 return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
344 }
345
346
347
348
349
350
351
352
353 if (card->chip_id > SDIO_CARD_ID_UNIFI_2)
354 {
355 unifi_info(card->ospriv, "Must convert f/w to patch format\n");
356 r = do_patch_convert_download(card, dlpriv, fwinfo);
357 }
358 else
359 {
360
361
362
363 unifi_error(card->ospriv, "Only patch downloading supported\n");
364 r = CSR_WIFI_HIP_RESULT_INVALID_VALUE;
365 }
366
367 kfree(fwinfo);
368 return r;
369}
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393CsrResult unifi_dl_patch(card_t *card, void *dlpriv, u32 boot_ctrl)
394{
395 xbv1_t *fwinfo;
396 CsrResult r;
397
398 unifi_info(card->ospriv, "unifi_dl_patch %p %08x\n", dlpriv, boot_ctrl);
399
400 fwinfo = kmalloc(sizeof(xbv1_t), GFP_KERNEL);
401 if (fwinfo == NULL)
402 {
403 unifi_error(card->ospriv, "Failed to allocate memory for patches\n");
404 return CSR_WIFI_HIP_RESULT_NO_MEMORY;
405 }
406
407
408
409
410
411
412
413
414 r = xbv1_parse(card, unifi_fw_read, dlpriv, fwinfo);
415 if (r != CSR_RESULT_SUCCESS || fwinfo->mode != xbv_patch)
416 {
417 kfree(fwinfo);
418 unifi_error(card->ospriv, "Failed to read in patch file\n");
419 return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
420 }
421
422
423
424
425
426
427 if (card->build_id != fwinfo->build_id)
428 {
429 unifi_error(card->ospriv, "Wrong patch file for chip (chip = %lu, file = %lu)\n",
430 card->build_id, fwinfo->build_id);
431 kfree(fwinfo);
432#ifndef CSR_WIFI_IGNORE_PATCH_VERSION_MISMATCH
433 return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
434#else
435 fwinfo = NULL;
436 dlpriv = NULL;
437 return CSR_RESULT_SUCCESS;
438#endif
439 }
440
441 r = do_patch_download(card, dlpriv, fwinfo, boot_ctrl);
442 if (r != CSR_RESULT_SUCCESS)
443 {
444 unifi_error(card->ospriv, "Failed to patch image\n");
445 }
446
447 kfree(fwinfo);
448
449 return r;
450}
451
452
453void* unifi_dl_fw_read_start(card_t *card, s8 is_fw)
454{
455 card_info_t card_info;
456
457 unifi_card_info(card, &card_info);
458 unifi_trace(card->ospriv, UDBG5,
459 "id=%d, ver=0x%x, fw_build=%u, fw_hip=0x%x, block_size=%d\n",
460 card_info.chip_id, card_info.chip_version,
461 card_info.fw_build, card_info.fw_hip_version,
462 card_info.sdio_block_size);
463
464 return unifi_fw_read_start(card->ospriv, is_fw, &card_info);
465}
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485static CsrResult safe_read_shared_location(card_t *card, u32 address, u8 *pdata)
486{
487 CsrResult r;
488 u16 limit = 1000;
489 u8 b, b2;
490
491 *pdata = 0;
492
493 r = unifi_read_8_or_16(card, address, &b);
494 if (r != CSR_RESULT_SUCCESS)
495 {
496 return r;
497 }
498
499 while (limit--)
500 {
501 r = unifi_read_8_or_16(card, address, &b2);
502 if (r != CSR_RESULT_SUCCESS)
503 {
504 return r;
505 }
506
507
508 if (b == b2)
509 {
510 *pdata = b;
511 return CSR_RESULT_SUCCESS;
512 }
513
514 b = b2;
515 }
516
517 return CSR_RESULT_FAILURE;
518}
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544#define OPERATION_TIMEOUT_LOOPS (100)
545#define OPERATION_TIMEOUT_DELAY 1
546
547CsrResult unifi_do_loader_op(card_t *card, u32 op_addr, u8 opcode)
548{
549 CsrResult r;
550 s16 op_retries;
551
552 unifi_trace(card->ospriv, UDBG4, "Loader cmd 0x%0x -> 0x%08x\n", opcode, op_addr);
553
554
555 r = unifi_write_8_or_16(card, op_addr, opcode);
556 if (r != CSR_RESULT_SUCCESS)
557 {
558 unifi_error(card->ospriv, "Failed to write loader copy command\n");
559 return r;
560 }
561
562
563
564 op_retries = 0;
565 r = CSR_RESULT_SUCCESS;
566 while (1)
567 {
568 u8 op;
569
570
571
572
573
574
575 r = safe_read_shared_location(card, op_addr, &op);
576 if (r != CSR_RESULT_SUCCESS)
577 {
578 unifi_error(card->ospriv, "Failed to read loader status\n");
579 break;
580 }
581
582 if (op == UNIFI_LOADER_IDLE)
583 {
584
585 break;
586 }
587
588 if (op != opcode)
589 {
590 unifi_error(card->ospriv, "Error reported by loader: 0x%X\n", op);
591 r = CSR_RESULT_FAILURE;
592 break;
593 }
594
595
596 if (++op_retries >= OPERATION_TIMEOUT_LOOPS)
597 {
598 unifi_error(card->ospriv, "Timeout waiting for loader to ack transfer\n");
599
600 r = unifi_card_stop_processor(card, UNIFI_PROC_BOTH);
601 if (r != CSR_RESULT_SUCCESS)
602 {
603 unifi_error(card->ospriv, "Failed to stop UniFi processors\n");
604 }
605 else
606 {
607 r = CSR_RESULT_FAILURE;
608 }
609 break;
610 }
611 CsrThreadSleep(OPERATION_TIMEOUT_DELAY);
612 }
613
614 return r;
615}
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641static CsrResult send_ptdl_to_unifi(card_t *card, void *dlpriv,
642 const struct PTDL *ptdl, u32 handle,
643 u32 op_addr)
644{
645 u32 offset;
646 u8 *buf;
647 s32 data_len;
648 u32 write_len;
649 CsrResult r;
650 const u16 buf_size = 2 * 1024;
651
652 offset = ptdl->dl_offset;
653 data_len = ptdl->dl_size;
654
655 if (data_len > buf_size)
656 {
657 unifi_error(card->ospriv, "PTDL block is too large (%u)\n",
658 ptdl->dl_size);
659 return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
660 }
661
662 buf = kmalloc(buf_size, GFP_KERNEL);
663 if (buf == NULL)
664 {
665 unifi_error(card->ospriv, "Failed to allocate transfer buffer for firmware download\n");
666 return CSR_WIFI_HIP_RESULT_NO_MEMORY;
667 }
668
669 r = CSR_RESULT_SUCCESS;
670
671 if (unifi_fw_read(card->ospriv, dlpriv, offset, buf, data_len) != data_len)
672 {
673 unifi_error(card->ospriv, "Failed to read from file\n");
674 }
675 else
676 {
677
678 if (card->sdio_io_block_pad)
679 {
680 write_len = (data_len + (card->sdio_io_block_size - 1)) &
681 ~(card->sdio_io_block_size - 1);
682
683
684
685 memset(buf + data_len, 0, write_len - data_len);
686 }
687 else
688 {
689 write_len = data_len;
690 }
691
692 r = unifi_bulk_rw_noretry(card, handle, buf, write_len, UNIFI_SDIO_WRITE);
693 if (r != CSR_RESULT_SUCCESS)
694 {
695 unifi_error(card->ospriv, "CMD53 failed writing %d bytes to handle %ld\n",
696 data_len, handle);
697 }
698 else
699 {
700
701
702
703
704 r = unifi_do_loader_op(card, op_addr, UNIFI_BOOT_LOADER_PATCH);
705 }
706 }
707
708 kfree(buf);
709
710 if (r != CSR_RESULT_SUCCESS && r != CSR_WIFI_HIP_RESULT_NO_DEVICE)
711 {
712 unifi_error(card->ospriv, "Failed to copy block of %u bytes to UniFi\n",
713 ptdl->dl_size);
714 }
715
716 return r;
717}
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741static CsrResult do_patch_download(card_t *card, void *dlpriv, xbv1_t *pfwinfo, u32 boot_ctrl_addr)
742{
743 CsrResult r;
744 s32 i;
745 u16 loader_version;
746 u16 handle;
747 u32 total_bytes;
748
749
750
751
752
753 r = unifi_card_read16(card, boot_ctrl_addr, &loader_version);
754 if (r != CSR_RESULT_SUCCESS)
755 {
756 unifi_error(card->ospriv, "Patch download: Failed to read loader version\n");
757 return r;
758 }
759 unifi_trace(card->ospriv, UDBG2, "Patch download: boot loader version 0x%04X\n", loader_version);
760 switch (loader_version)
761 {
762 case 0x0000:
763 break;
764
765 default:
766 unifi_error(card->ospriv, "Patch loader version (0x%04X) is not supported by this driver\n",
767 loader_version);
768 return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
769 }
770
771
772 r = unifi_card_read16(card, boot_ctrl_addr + 4, &handle);
773 if (r != CSR_RESULT_SUCCESS)
774 {
775 unifi_error(card->ospriv, "Patch download: Failed to read loader handle\n");
776 return r;
777 }
778
779
780 if (card->loader_led_mask)
781 {
782 r = unifi_card_write16(card, boot_ctrl_addr + 2,
783 (u16)card->loader_led_mask);
784 if (r != CSR_RESULT_SUCCESS)
785 {
786 unifi_error(card->ospriv, "Patch download: Failed to write LED mask\n");
787 return r;
788 }
789 }
790
791 total_bytes = 0;
792
793
794 for (i = 0; i < pfwinfo->num_ptdl; i++)
795 {
796 unifi_trace(card->ospriv, UDBG3, "Patch download: %d Downloading for %d from offset %d\n",
797 i,
798 pfwinfo->ptdl[i].dl_size,
799 pfwinfo->ptdl[i].dl_offset);
800
801 r = send_ptdl_to_unifi(card, dlpriv, &pfwinfo->ptdl[i],
802 handle, boot_ctrl_addr + 6);
803 if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
804 {
805 return r;
806 }
807 if (r != CSR_RESULT_SUCCESS)
808 {
809 unifi_error(card->ospriv, "Patch failed after %u bytes\n",
810 total_bytes);
811 return r;
812 }
813 total_bytes += pfwinfo->ptdl[i].dl_size;
814 }
815
816 return CSR_RESULT_SUCCESS;
817}
818
819
820