1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include "csr_wifi_hip_unifi.h"
20#include "csr_wifi_hip_card.h"
21
22#define SDIO_RETRIES 3
23#define CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH 16
24
25
26#define retryable_sdio_error(_csrResult) (((_csrResult) == CSR_SDIO_RESULT_CRC_ERROR) || ((_csrResult) == CSR_SDIO_RESULT_TIMEOUT))
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56static CsrResult retrying_read8(card_t *card, s16 funcnum, u32 addr, u8 *pdata)
57{
58 CsrSdioFunction *sdio = card->sdio_if;
59 CsrResult r = CSR_RESULT_SUCCESS;
60 s16 retries;
61 CsrResult csrResult = CSR_RESULT_SUCCESS;
62
63 retries = 0;
64 while (retries++ < SDIO_RETRIES)
65 {
66 if (funcnum == 0)
67 {
68#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
69 unifi_debug_log_to_buf("r0@%02X", addr);
70#endif
71 csrResult = CsrSdioF0Read8(sdio, addr, pdata);
72 }
73 else
74 {
75#ifdef CSR_WIFI_TRANSPORT_CSPI
76 unifi_error(card->ospriv,
77 "retrying_read_f0_8: F1 8-bit reads are not allowed.\n");
78 return CSR_RESULT_FAILURE;
79#else
80#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
81 unifi_debug_log_to_buf("r@%02X", addr);
82#endif
83 csrResult = CsrSdioRead8(sdio, addr, pdata);
84#endif
85 }
86#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
87 if (csrResult != CSR_RESULT_SUCCESS)
88 {
89 unifi_debug_log_to_buf("error=%X\n", csrResult);
90 }
91 else
92 {
93 unifi_debug_log_to_buf("=%X\n", *pdata);
94 }
95#endif
96 if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
97 {
98 return CSR_WIFI_HIP_RESULT_NO_DEVICE;
99 }
100
101
102
103
104 if (!retryable_sdio_error(csrResult))
105 {
106#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
107 card->cmd_prof.cmd52_count++;
108#endif
109 break;
110 }
111 unifi_trace(card->ospriv, UDBG2, "retryable SDIO error reading F%d 0x%lX\n", funcnum, addr);
112 }
113
114 if ((csrResult == CSR_RESULT_SUCCESS) && (retries > 1))
115 {
116 unifi_warning(card->ospriv, "Read succeeded after %d attempts\n", retries);
117 }
118
119 if (csrResult != CSR_RESULT_SUCCESS)
120 {
121 unifi_error(card->ospriv, "Failed to read from UniFi (addr 0x%lX) after %d tries\n",
122 addr, retries - 1);
123
124 r = CSR_RESULT_FAILURE;
125 }
126
127 return r;
128}
129
130
131static CsrResult retrying_write8(card_t *card, s16 funcnum, u32 addr, u8 data)
132{
133 CsrSdioFunction *sdio = card->sdio_if;
134 CsrResult r = CSR_RESULT_SUCCESS;
135 s16 retries;
136 CsrResult csrResult = CSR_RESULT_SUCCESS;
137
138 retries = 0;
139 while (retries++ < SDIO_RETRIES)
140 {
141 if (funcnum == 0)
142 {
143#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
144 unifi_debug_log_to_buf("w0@%02X=%X", addr, data);
145#endif
146 csrResult = CsrSdioF0Write8(sdio, addr, data);
147 }
148 else
149 {
150#ifdef CSR_WIFI_TRANSPORT_CSPI
151 unifi_error(card->ospriv,
152 "retrying_write_f0_8: F1 8-bit writes are not allowed.\n");
153 return CSR_RESULT_FAILURE;
154#else
155#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
156 unifi_debug_log_to_buf("w@%02X=%X", addr, data);
157#endif
158 csrResult = CsrSdioWrite8(sdio, addr, data);
159#endif
160 }
161#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
162 if (csrResult != CSR_RESULT_SUCCESS)
163 {
164 unifi_debug_log_to_buf(",error=%X", csrResult);
165 }
166 unifi_debug_string_to_buf("\n");
167#endif
168 if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
169 {
170 return CSR_WIFI_HIP_RESULT_NO_DEVICE;
171 }
172
173
174
175
176 if (!retryable_sdio_error(csrResult))
177 {
178#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
179 card->cmd_prof.cmd52_count++;
180#endif
181 break;
182 }
183 unifi_trace(card->ospriv, UDBG2, "retryable SDIO error writing %02X to F%d 0x%lX\n",
184 data, funcnum, addr);
185 }
186
187 if ((csrResult == CSR_RESULT_SUCCESS) && (retries > 1))
188 {
189 unifi_warning(card->ospriv, "Write succeeded after %d attempts\n", retries);
190 }
191
192 if (csrResult != CSR_RESULT_SUCCESS)
193 {
194 unifi_error(card->ospriv, "Failed to write to UniFi (addr 0x%lX) after %d tries\n",
195 addr, retries - 1);
196
197 r = CSR_RESULT_FAILURE;
198 }
199
200 return r;
201}
202
203
204static CsrResult retrying_read16(card_t *card, s16 funcnum,
205 u32 addr, u16 *pdata)
206{
207 CsrSdioFunction *sdio = card->sdio_if;
208 CsrResult r = CSR_RESULT_SUCCESS;
209 s16 retries;
210 CsrResult csrResult = CSR_RESULT_SUCCESS;
211
212 retries = 0;
213 while (retries++ < SDIO_RETRIES)
214 {
215#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
216 unifi_debug_log_to_buf("r@%02X", addr);
217#endif
218 csrResult = CsrSdioRead16(sdio, addr, pdata);
219#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
220 if (csrResult != CSR_RESULT_SUCCESS)
221 {
222 unifi_debug_log_to_buf("error=%X\n", csrResult);
223 }
224 else
225 {
226 unifi_debug_log_to_buf("=%X\n", *pdata);
227 }
228#endif
229 if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
230 {
231 return CSR_WIFI_HIP_RESULT_NO_DEVICE;
232 }
233
234
235
236
237
238 if (!retryable_sdio_error(csrResult))
239 {
240#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
241 card->cmd_prof.cmd52_count++;
242#endif
243 break;
244 }
245 unifi_trace(card->ospriv, UDBG2, "retryable SDIO error reading F%d 0x%lX\n", funcnum, addr);
246 }
247
248 if ((csrResult == CSR_RESULT_SUCCESS) && (retries > 1))
249 {
250 unifi_warning(card->ospriv, "Read succeeded after %d attempts\n", retries);
251 }
252
253 if (csrResult != CSR_RESULT_SUCCESS)
254 {
255 unifi_error(card->ospriv, "Failed to read from UniFi (addr 0x%lX) after %d tries\n",
256 addr, retries - 1);
257
258 r = CSR_RESULT_FAILURE;
259 }
260
261 return r;
262}
263
264
265static CsrResult retrying_write16(card_t *card, s16 funcnum,
266 u32 addr, u16 data)
267{
268 CsrSdioFunction *sdio = card->sdio_if;
269 CsrResult r = CSR_RESULT_SUCCESS;
270 s16 retries;
271 CsrResult csrResult = CSR_RESULT_SUCCESS;
272
273 retries = 0;
274 while (retries++ < SDIO_RETRIES)
275 {
276#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
277 unifi_debug_log_to_buf("w@%02X=%X", addr, data);
278#endif
279 csrResult = CsrSdioWrite16(sdio, addr, data);
280#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
281 if (csrResult != CSR_RESULT_SUCCESS)
282 {
283 unifi_debug_log_to_buf(",error=%X", csrResult);
284 }
285 unifi_debug_string_to_buf("\n");
286#endif
287 if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
288 {
289 return CSR_WIFI_HIP_RESULT_NO_DEVICE;
290 }
291
292
293
294
295
296 if (!retryable_sdio_error(csrResult))
297 {
298#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
299 card->cmd_prof.cmd52_count++;
300#endif
301 break;
302 }
303 unifi_trace(card->ospriv, UDBG2, "retryable SDIO error writing %02X to F%d 0x%lX\n",
304 data, funcnum, addr);
305 }
306
307 if ((csrResult == CSR_RESULT_SUCCESS) && (retries > 1))
308 {
309 unifi_warning(card->ospriv, "Write succeeded after %d attempts\n", retries);
310 }
311
312 if (csrResult != CSR_RESULT_SUCCESS)
313 {
314 unifi_error(card->ospriv, "Failed to write to UniFi (addr 0x%lX) after %d tries\n",
315 addr, retries - 1);
316
317 r = CSR_RESULT_FAILURE;
318 }
319
320 return r;
321}
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341CsrResult sdio_read_f0(card_t *card, u32 addr, u8 *pdata)
342{
343#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
344 card->cmd_prof.cmd52_f0_r_count++;
345#endif
346 return retrying_read8(card, 0, addr, pdata);
347}
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367CsrResult sdio_write_f0(card_t *card, u32 addr, u8 data)
368{
369#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
370 card->cmd_prof.cmd52_f0_w_count++;
371#endif
372 return retrying_write8(card, 0, addr, data);
373}
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391CsrResult unifi_read_direct_8_or_16(card_t *card, u32 addr, u8 *pdata)
392{
393#ifdef CSR_WIFI_TRANSPORT_CSPI
394 u16 w;
395 CsrResult r;
396
397 r = retrying_read16(card, card->function, addr, &w);
398 *pdata = (u8)(w & 0xFF);
399 return r;
400#else
401 return retrying_read8(card, card->function, addr, pdata);
402#endif
403}
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426CsrResult unifi_write_direct_8_or_16(card_t *card, u32 addr, u8 data)
427{
428 if (addr & 1)
429 {
430 unifi_warning(card->ospriv,
431 "Warning: Byte write to an odd address (0x%lX) is dangerous\n",
432 addr);
433 }
434
435#ifdef CSR_WIFI_TRANSPORT_CSPI
436 return retrying_write16(card, card->function, addr, (u16)data);
437#else
438 return retrying_write8(card, card->function, addr, data);
439#endif
440}
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465CsrResult unifi_read_direct16(card_t *card, u32 addr, u16 *pdata)
466{
467 return retrying_read16(card, card->function, addr, pdata);
468}
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493CsrResult unifi_write_direct16(card_t *card, u32 addr, u16 data)
494{
495 return retrying_write16(card, card->function, addr, data);
496}
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516CsrResult unifi_read_direct32(card_t *card, u32 addr, u32 *pdata)
517{
518 CsrResult r;
519 u16 w0, w1;
520
521 r = retrying_read16(card, card->function, addr, &w0);
522 if (r != CSR_RESULT_SUCCESS)
523 {
524 return r;
525 }
526
527 r = retrying_read16(card, card->function, addr + 2, &w1);
528 if (r != CSR_RESULT_SUCCESS)
529 {
530 return r;
531 }
532
533 *pdata = ((u32)w1 << 16) | (u32)w0;
534
535 return CSR_RESULT_SUCCESS;
536}
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567static CsrResult unifi_read_directn_match(card_t *card, u32 addr, void *pdata, u16 len, s8 m, u32 *num)
568{
569 CsrResult r;
570 u32 i;
571 u8 *cptr;
572 u16 w;
573
574 *num = 0;
575
576 cptr = (u8 *)pdata;
577 for (i = 0; i < len; i += 2)
578 {
579 r = retrying_read16(card, card->function, addr, &w);
580 if (r != CSR_RESULT_SUCCESS)
581 {
582 return r;
583 }
584
585 *cptr++ = ((u8)w & 0xFF);
586 if ((m >= 0) && (((s8)w & 0xFF) == m))
587 {
588 break;
589 }
590
591 if (i + 1 == len)
592 {
593
594 break;
595 }
596
597 *cptr++ = ((u8)(w >> 8) & 0xFF);
598 if ((m >= 0) && (((s8)(w >> 8) & 0xFF) == m))
599 {
600 break;
601 }
602
603 addr += 2;
604 }
605
606 *num = (s32)(cptr - (u8 *)pdata);
607 return CSR_RESULT_SUCCESS;
608}
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634CsrResult unifi_read_directn(card_t *card, u32 addr, void *pdata, u16 len)
635{
636 u32 num;
637
638 return unifi_read_directn_match(card, addr, pdata, len, -1, &num);
639}
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667CsrResult unifi_write_directn(card_t *card, u32 addr, void *pdata, u16 len)
668{
669 CsrResult r;
670 u8 *cptr;
671 s16 signed_len;
672
673 cptr = (u8 *)pdata;
674 signed_len = (s16)len;
675 while (signed_len > 0)
676 {
677
678 r = retrying_write16(card, card->function, addr, *cptr);
679 if (r != CSR_RESULT_SUCCESS)
680 {
681 return r;
682 }
683
684 cptr += 2;
685 addr += 2;
686 signed_len -= 2;
687 }
688
689 return CSR_RESULT_SUCCESS;
690}
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717static CsrResult set_dmem_page(card_t *card, u32 dmem_addr, u32 *paddr)
718{
719 u16 page, addr;
720 u32 len;
721 CsrResult r;
722
723 *paddr = 0;
724
725 if (!ChipHelper_DecodeWindow(card->helper,
726 CHIP_HELPER_WINDOW_3,
727 CHIP_HELPER_WT_SHARED,
728 dmem_addr / 2,
729 &page, &addr, &len))
730 {
731 unifi_error(card->ospriv, "Failed to decode SHARED_DMEM_PAGE %08lx\n", dmem_addr);
732 return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
733 }
734
735 if (page != card->dmem_page)
736 {
737 unifi_trace(card->ospriv, UDBG6, "setting dmem page=0x%X, addr=0x%lX\n", page, addr);
738
739
740 r = unifi_write_direct16(card, ChipHelper_HOST_WINDOW3_PAGE(card->helper) * 2, page);
741 if (r != CSR_RESULT_SUCCESS)
742 {
743 unifi_error(card->ospriv, "Failed to write SHARED_DMEM_PAGE\n");
744 return r;
745 }
746
747 card->dmem_page = page;
748 }
749
750 *paddr = ((s32)addr * 2) + (dmem_addr & 1);
751
752 return CSR_RESULT_SUCCESS;
753}
754
755
756static CsrResult set_pmem_page(card_t *card, u32 pmem_addr,
757 enum chip_helper_window_type mem_type, u32 *paddr)
758{
759 u16 page, addr;
760 u32 len;
761 CsrResult r;
762
763 *paddr = 0;
764
765 if (!ChipHelper_DecodeWindow(card->helper,
766 CHIP_HELPER_WINDOW_2,
767 mem_type,
768 pmem_addr / 2,
769 &page, &addr, &len))
770 {
771 unifi_error(card->ospriv, "Failed to decode PROG MEM PAGE %08lx %d\n", pmem_addr, mem_type);
772 return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
773 }
774
775 if (page != card->pmem_page)
776 {
777 unifi_trace(card->ospriv, UDBG6, "setting pmem page=0x%X, addr=0x%lX\n", page, addr);
778
779
780 r = unifi_write_direct16(card, ChipHelper_HOST_WINDOW2_PAGE(card->helper) * 2, page);
781 if (r != CSR_RESULT_SUCCESS)
782 {
783 unifi_error(card->ospriv, "Failed to write PROG MEM PAGE\n");
784 return r;
785 }
786
787 card->pmem_page = page;
788 }
789
790 *paddr = ((s32)addr * 2) + (pmem_addr & 1);
791
792 return CSR_RESULT_SUCCESS;
793}
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817static CsrResult set_page(card_t *card, u32 generic_addr, u32 *paddr)
818{
819 s32 space;
820 u32 addr;
821 CsrResult r = CSR_RESULT_SUCCESS;
822
823 if (!paddr)
824 {
825 return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
826 }
827 *paddr = 0;
828 space = UNIFI_GP_SPACE(generic_addr);
829 addr = UNIFI_GP_OFFSET(generic_addr);
830 switch (space)
831 {
832 case UNIFI_SH_DMEM:
833
834 r = set_dmem_page(card, addr, paddr);
835 if (r != CSR_RESULT_SUCCESS)
836 {
837 return r;
838 }
839 break;
840
841 case UNIFI_EXT_FLASH:
842 if (!ChipHelper_HasFlash(card->helper))
843 {
844 unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
845 generic_addr, card->helper);
846 return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
847 }
848
849 r = set_pmem_page(card, addr, CHIP_HELPER_WT_FLASH, paddr);
850 break;
851
852 case UNIFI_EXT_SRAM:
853 if (!ChipHelper_HasExtSram(card->helper))
854 {
855 unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08l (helper=0x%x)\n",
856 generic_addr, card->helper);
857 return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
858 }
859
860 r = set_pmem_page(card, addr, CHIP_HELPER_WT_EXT_SRAM, paddr);
861 break;
862
863 case UNIFI_REGISTERS:
864
865 *paddr = addr;
866 break;
867
868 case UNIFI_PHY_DMEM:
869 r = unifi_set_proc_select(card, UNIFI_PROC_PHY);
870 if (r != CSR_RESULT_SUCCESS)
871 {
872 return r;
873 }
874 *paddr = ChipHelper_DATA_MEMORY_RAM_OFFSET(card->helper) * 2 + addr;
875 break;
876
877 case UNIFI_MAC_DMEM:
878 r = unifi_set_proc_select(card, UNIFI_PROC_MAC);
879 if (r != CSR_RESULT_SUCCESS)
880 {
881 return r;
882 }
883 *paddr = ChipHelper_DATA_MEMORY_RAM_OFFSET(card->helper) * 2 + addr;
884 break;
885
886 case UNIFI_BT_DMEM:
887 if (!ChipHelper_HasBt(card->helper))
888 {
889 unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
890 generic_addr, card->helper);
891 return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
892 }
893 r = unifi_set_proc_select(card, UNIFI_PROC_BT);
894 if (r != CSR_RESULT_SUCCESS)
895 {
896 return r;
897 }
898 *paddr = ChipHelper_DATA_MEMORY_RAM_OFFSET(card->helper) * 2 + addr;
899 break;
900
901 case UNIFI_PHY_PMEM:
902 r = unifi_set_proc_select(card, UNIFI_PROC_PHY);
903 if (r != CSR_RESULT_SUCCESS)
904 {
905 return r;
906 }
907 r = set_pmem_page(card, addr, CHIP_HELPER_WT_CODE_RAM, paddr);
908 break;
909
910 case UNIFI_MAC_PMEM:
911 r = unifi_set_proc_select(card, UNIFI_PROC_MAC);
912 if (r != CSR_RESULT_SUCCESS)
913 {
914 return r;
915 }
916 r = set_pmem_page(card, addr, CHIP_HELPER_WT_CODE_RAM, paddr);
917 break;
918
919 case UNIFI_BT_PMEM:
920 if (!ChipHelper_HasBt(card->helper))
921 {
922 unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
923 generic_addr, card->helper);
924 return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
925 }
926 r = unifi_set_proc_select(card, UNIFI_PROC_BT);
927 if (r != CSR_RESULT_SUCCESS)
928 {
929 return r;
930 }
931 r = set_pmem_page(card, addr, CHIP_HELPER_WT_CODE_RAM, paddr);
932 break;
933
934 case UNIFI_PHY_ROM:
935 if (!ChipHelper_HasRom(card->helper))
936 {
937 unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
938 generic_addr, card->helper);
939 return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
940 }
941 r = unifi_set_proc_select(card, UNIFI_PROC_PHY);
942 if (r != CSR_RESULT_SUCCESS)
943 {
944 return r;
945 }
946 r = set_pmem_page(card, addr, CHIP_HELPER_WT_ROM, paddr);
947 break;
948
949 case UNIFI_MAC_ROM:
950 if (!ChipHelper_HasRom(card->helper))
951 {
952 unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
953 generic_addr, card->helper);
954 return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
955 }
956 r = unifi_set_proc_select(card, UNIFI_PROC_MAC);
957 if (r != CSR_RESULT_SUCCESS)
958 {
959 return r;
960 }
961 r = set_pmem_page(card, addr, CHIP_HELPER_WT_ROM, paddr);
962 break;
963
964 case UNIFI_BT_ROM:
965 if (!ChipHelper_HasRom(card->helper) || !ChipHelper_HasBt(card->helper))
966 {
967 unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
968 generic_addr, card->helper);
969 return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
970 }
971 r = unifi_set_proc_select(card, UNIFI_PROC_BT);
972 if (r != CSR_RESULT_SUCCESS)
973 {
974 return r;
975 }
976 r = set_pmem_page(card, addr, CHIP_HELPER_WT_ROM, paddr);
977 break;
978
979 default:
980 unifi_error(card->ospriv, "Bad address space %d in generic pointer 0x%08lX (helper=0x%x)\n",
981 space, generic_addr, card->helper);
982 return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
983 }
984
985 return r;
986}
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004CsrResult unifi_set_proc_select(card_t *card, enum unifi_dbg_processors_select select)
1005{
1006 CsrResult r;
1007
1008
1009 switch (select)
1010 {
1011 case UNIFI_PROC_MAC:
1012 case UNIFI_PROC_PHY:
1013 case UNIFI_PROC_BOTH:
1014 break;
1015
1016
1017 default:
1018 return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
1019 }
1020
1021 if (card->proc_select != (u32)select)
1022 {
1023 r = unifi_write_direct16(card,
1024 ChipHelper_DBG_HOST_PROC_SELECT(card->helper) * 2,
1025 (u8)select);
1026 if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
1027 {
1028 return r;
1029 }
1030 if (r != CSR_RESULT_SUCCESS)
1031 {
1032 unifi_error(card->ospriv, "Failed to write to Proc Select register\n");
1033 return r;
1034 }
1035
1036 card->proc_select = (u32)select;
1037 }
1038
1039 return CSR_RESULT_SUCCESS;
1040}
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062CsrResult unifi_read_8_or_16(card_t *card, u32 unifi_addr, u8 *pdata)
1063{
1064 u32 sdio_addr;
1065 CsrResult r;
1066#ifdef CSR_WIFI_TRANSPORT_CSPI
1067 u16 w;
1068#endif
1069
1070 r = set_page(card, unifi_addr, &sdio_addr);
1071 if (r != CSR_RESULT_SUCCESS)
1072 {
1073 return r;
1074 }
1075
1076#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1077 card->cmd_prof.cmd52_r8or16_count++;
1078#endif
1079#ifdef CSR_WIFI_TRANSPORT_CSPI
1080 r = retrying_read16(card, card->function, sdio_addr, &w);
1081 *pdata = (u8)(w & 0xFF);
1082 return r;
1083#else
1084 return retrying_read8(card, card->function, sdio_addr, pdata);
1085#endif
1086}
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113CsrResult unifi_write_8_or_16(card_t *card, u32 unifi_addr, u8 data)
1114{
1115 u32 sdio_addr;
1116 CsrResult r;
1117#ifdef CSR_WIFI_TRANSPORT_CSPI
1118 u16 w;
1119#endif
1120
1121 r = set_page(card, unifi_addr, &sdio_addr);
1122 if (r != CSR_RESULT_SUCCESS)
1123 {
1124 return r;
1125 }
1126
1127 if (sdio_addr & 1)
1128 {
1129 unifi_warning(card->ospriv,
1130 "Warning: Byte write to an odd address (0x%lX) is dangerous\n",
1131 sdio_addr);
1132 }
1133
1134#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1135 card->cmd_prof.cmd52_w8or16_count++;
1136#endif
1137#ifdef CSR_WIFI_TRANSPORT_CSPI
1138 w = data;
1139 return retrying_write16(card, card->function, sdio_addr, w);
1140#else
1141 return retrying_write8(card, card->function, sdio_addr, data);
1142#endif
1143}
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165CsrResult unifi_card_read16(card_t *card, u32 unifi_addr, u16 *pdata)
1166{
1167 u32 sdio_addr;
1168 CsrResult r;
1169
1170 r = set_page(card, unifi_addr, &sdio_addr);
1171 if (r != CSR_RESULT_SUCCESS)
1172 {
1173 return r;
1174 }
1175
1176#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1177 card->cmd_prof.cmd52_r16_count++;
1178#endif
1179 return unifi_read_direct16(card, sdio_addr, pdata);
1180}
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202CsrResult unifi_card_write16(card_t *card, u32 unifi_addr, u16 data)
1203{
1204 u32 sdio_addr;
1205 CsrResult r;
1206
1207 r = set_page(card, unifi_addr, &sdio_addr);
1208 if (r != CSR_RESULT_SUCCESS)
1209 {
1210 return r;
1211 }
1212
1213#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1214 card->cmd_prof.cmd52_w16_count++;
1215#endif
1216 return unifi_write_direct16(card, sdio_addr, data);
1217}
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239CsrResult unifi_read32(card_t *card, u32 unifi_addr, u32 *pdata)
1240{
1241 u32 sdio_addr;
1242 CsrResult r;
1243
1244 r = set_page(card, unifi_addr, &sdio_addr);
1245 if (r != CSR_RESULT_SUCCESS)
1246 {
1247 return r;
1248 }
1249
1250#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1251 card->cmd_prof.cmd52_r32_count++;
1252#endif
1253 return unifi_read_direct32(card, sdio_addr, pdata);
1254}
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281CsrResult unifi_readn_match(card_t *card, u32 unifi_addr, void *pdata, u16 len, s8 match)
1282{
1283 u32 sdio_addr;
1284 CsrResult r;
1285 u32 num;
1286
1287 r = set_page(card, unifi_addr, &sdio_addr);
1288 if (r != CSR_RESULT_SUCCESS)
1289 {
1290 return r;
1291 }
1292
1293 r = unifi_read_directn_match(card, sdio_addr, pdata, len, match, &num);
1294 return r;
1295}
1296
1297
1298CsrResult unifi_card_readn(card_t *card, u32 unifi_addr, void *pdata, u16 len)
1299{
1300 return unifi_readn_match(card, unifi_addr, pdata, len, -1);
1301}
1302
1303
1304CsrResult unifi_readnz(card_t *card, u32 unifi_addr, void *pdata, u16 len)
1305{
1306 return unifi_readn_match(card, unifi_addr, pdata, len, 0);
1307}
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326s32 unifi_read_shared_count(card_t *card, u32 addr)
1327{
1328 u8 b;
1329
1330
1331
1332
1333
1334#define SHARED_READ_RETRY_LIMIT 10
1335 s32 i;
1336
1337
1338
1339
1340
1341
1342
1343 for (i = 0; i < SHARED_READ_RETRY_LIMIT; i++)
1344 {
1345 CsrResult r;
1346 r = unifi_read_8_or_16(card, addr, &b);
1347 if (r != CSR_RESULT_SUCCESS)
1348 {
1349 return -1;
1350 }
1351 if (!(b & 0x80))
1352 {
1353
1354
1355
1356
1357
1358 return (s32)(b & 0xff);
1359 }
1360 }
1361
1362 return -1;
1363}
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387CsrResult unifi_writen(card_t *card, u32 unifi_addr, void *pdata, u16 len)
1388{
1389 u32 sdio_addr;
1390 CsrResult r;
1391
1392 r = set_page(card, unifi_addr, &sdio_addr);
1393 if (r != CSR_RESULT_SUCCESS)
1394 {
1395 return r;
1396 }
1397
1398 return unifi_write_directn(card, sdio_addr, pdata, len);
1399}
1400
1401
1402static CsrResult csr_sdio_block_rw(card_t *card, s16 funcnum,
1403 u32 addr, u8 *pdata,
1404 u16 count, s16 dir_is_write)
1405{
1406 CsrResult csrResult;
1407
1408 if (dir_is_write == UNIFI_SDIO_READ)
1409 {
1410#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
1411 unifi_debug_log_to_buf("r@%02X#%X=", addr, count);
1412#endif
1413#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1414 unifi_debug_log_to_buf("R");
1415#endif
1416 csrResult = CsrSdioRead(card->sdio_if, addr, pdata, count);
1417#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1418 unifi_debug_log_to_buf("<");
1419#endif
1420 }
1421 else
1422 {
1423#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
1424 unifi_debug_log_to_buf("w@%02X#%X=", addr, count);
1425 unifi_debug_hex_to_buf(pdata, count > CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH?CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH : count);
1426#endif
1427#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1428 unifi_debug_log_to_buf("W");
1429#endif
1430 csrResult = CsrSdioWrite(card->sdio_if, addr, pdata, count);
1431#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1432 unifi_debug_log_to_buf(">");
1433#endif
1434 }
1435#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
1436 card->cmd_prof.cmd53_count++;
1437#endif
1438#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
1439 if (csrResult != CSR_RESULT_SUCCESS)
1440 {
1441 unifi_debug_log_to_buf("error=%X", csrResult);
1442 }
1443 else if (dir_is_write == UNIFI_SDIO_READ)
1444 {
1445 unifi_debug_hex_to_buf(pdata, count > CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH?CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH : count);
1446 }
1447 unifi_debug_string_to_buf("\n");
1448#endif
1449 return csrResult;
1450}
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475CsrResult unifi_bulk_rw(card_t *card, u32 handle, void *pdata,
1476 u32 len, s16 direction)
1477{
1478#define CMD53_RETRIES 3
1479
1480
1481
1482
1483
1484#define REWIND_RETRIES 15
1485#define REWIND_POLLING_RETRIES 5
1486#define REWIND_DELAY 1
1487 CsrResult csrResult;
1488 CsrResult r = CSR_RESULT_SUCCESS;
1489 s16 retries = CMD53_RETRIES;
1490 s16 stat_retries;
1491 u8 stat;
1492 s16 dump_read;
1493#ifdef UNIFI_DEBUG
1494 u8 *pdata_lsb = ((u8 *)&pdata) + card->lsb;
1495#endif
1496#ifdef CSR_WIFI_MAKE_FAKE_CMD53_ERRORS
1497 static s16 fake_error;
1498#endif
1499
1500 dump_read = 0;
1501#ifdef UNIFI_DEBUG
1502 if (*pdata_lsb & 1)
1503 {
1504 unifi_notice(card->ospriv, "CD53 request on a unaligned buffer (addr: 0x%X) dir %s-Host\n",
1505 pdata, (direction == UNIFI_SDIO_READ)?"To" : "From");
1506 if (direction == UNIFI_SDIO_WRITE)
1507 {
1508 dump(pdata, (u16)len);
1509 }
1510 else
1511 {
1512 dump_read = 1;
1513 }
1514 }
1515#endif
1516
1517
1518 if (!pdata)
1519 {
1520 unifi_error(card->ospriv, "Null pdata for unifi_bulk_rw() len: %d\n", len);
1521 return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
1522 }
1523 if ((len & 1) || (len > 0xffff))
1524 {
1525 unifi_error(card->ospriv, "Impossible CMD53 length requested: %d\n", len);
1526 return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
1527 }
1528
1529 while (1)
1530 {
1531 csrResult = csr_sdio_block_rw(card, card->function, handle,
1532 (u8 *)pdata, (u16)len,
1533 direction);
1534 if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
1535 {
1536 return CSR_WIFI_HIP_RESULT_NO_DEVICE;
1537 }
1538#ifdef CSR_WIFI_MAKE_FAKE_CMD53_ERRORS
1539 if (++fake_error > 100)
1540 {
1541 fake_error = 90;
1542 unifi_warning(card->ospriv, "Faking a CMD53 error,\n");
1543 if (csrResult == CSR_RESULT_SUCCESS)
1544 {
1545 csrResult = CSR_RESULT_FAILURE;
1546 }
1547 }
1548#endif
1549 if (csrResult == CSR_RESULT_SUCCESS)
1550 {
1551 if (dump_read)
1552 {
1553 dump(pdata, (u16)len);
1554 }
1555 break;
1556 }
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566 if (card->chip_id <= SDIO_CARD_ID_UNIFI_2)
1567 {
1568 (void)unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
1569 }
1570
1571
1572
1573
1574 if (!retryable_sdio_error(csrResult))
1575 {
1576 unifi_error(card->ospriv, "Fatal error in a CMD53 transfer\n");
1577 break;
1578 }
1579
1580
1581
1582
1583 if (--retries == 0)
1584 {
1585 break;
1586 }
1587
1588 unifi_trace(card->ospriv, UDBG4,
1589 "Error in a CMD53 transfer, retrying (h:%d,l:%u)...\n",
1590 (s16)handle & 0xff, len);
1591
1592
1593 r = unifi_write_8_or_16(card, card->sdio_ctrl_addr + 8,
1594 (u8)(handle & 0xff));
1595 if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
1596 {
1597 return r;
1598 }
1599 if (r != CSR_RESULT_SUCCESS)
1600 {
1601
1602
1603
1604
1605 unifi_error(card->ospriv, "Failed to write REWIND cmd\n");
1606 return r;
1607 }
1608
1609
1610 r = CardGenInt(card);
1611 if (r != CSR_RESULT_SUCCESS)
1612 {
1613 return r;
1614 }
1615
1616
1617 stat_retries = REWIND_RETRIES;
1618 while (1)
1619 {
1620 r = unifi_read_8_or_16(card, card->sdio_ctrl_addr + 8, &stat);
1621 if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
1622 {
1623 return r;
1624 }
1625 if (r != CSR_RESULT_SUCCESS)
1626 {
1627 unifi_error(card->ospriv, "Failed to read REWIND status\n");
1628 return CSR_RESULT_FAILURE;
1629 }
1630
1631 if (stat == 0)
1632 {
1633 break;
1634 }
1635 if (--stat_retries == 0)
1636 {
1637 unifi_error(card->ospriv, "Timeout waiting for REWIND ready\n");
1638 return CSR_RESULT_FAILURE;
1639 }
1640
1641
1642 if (stat_retries < REWIND_RETRIES - REWIND_POLLING_RETRIES)
1643 {
1644 CsrThreadSleep(REWIND_DELAY);
1645 }
1646 }
1647 }
1648
1649
1650 if (csrResult != CSR_RESULT_SUCCESS)
1651 {
1652 unifi_error(card->ospriv, "Block %s failed after %d retries\n",
1653 (direction == UNIFI_SDIO_READ)?"read" : "write",
1654 CMD53_RETRIES - retries);
1655
1656 return CSR_RESULT_FAILURE;
1657 }
1658
1659
1660 if (direction == UNIFI_SDIO_READ)
1661 {
1662 card->sdio_bytes_read += len;
1663 }
1664 else
1665 {
1666 card->sdio_bytes_written += len;
1667 }
1668
1669 return CSR_RESULT_SUCCESS;
1670}
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696CsrResult unifi_bulk_rw_noretry(card_t *card, u32 handle, void *pdata,
1697 u32 len, s16 direction)
1698{
1699 CsrResult csrResult;
1700
1701 csrResult = csr_sdio_block_rw(card, card->function, handle,
1702 (u8 *)pdata, (u16)len, direction);
1703 if (csrResult != CSR_RESULT_SUCCESS)
1704 {
1705 unifi_error(card->ospriv, "Block %s failed\n",
1706 (direction == UNIFI_SDIO_READ)?"read" : "write");
1707 return csrResult;
1708 }
1709
1710 return CSR_RESULT_SUCCESS;
1711}
1712
1713
1714