1
2
3
4
5
6
7
8
9
10
11#include "csr_macro.h"
12#include "csr_wifi_hip_chiphelper_private.h"
13
14#ifndef nelem
15#define nelem(a) (sizeof(a) / sizeof(a[0]))
16#endif
17
18#define counted(foo) { nelem(foo), foo }
19#define null_counted() { 0, NULL }
20
21
22
23
24
25
26
27static const struct chip_helper_init_values init_vals_v1[] = {
28 { 0xFDBB, 0xFFFF },
29 { 0xFDB6, 0x03FF },
30 { 0xFDB1, 0x01E3 },
31 { 0xFDB3, 0x0FFF },
32 { 0xFEE3, 0x08F0 },
33 { 0xFEE7, 0x3C3F },
34 { 0xFEE6, 0x0050 },
35 { 0xFDBA, 0x0000 }
36};
37
38static const struct chip_helper_init_values init_vals_v2[] = {
39 { 0xFDB6, 0x0FFF },
40 { 0xF023, 0x3F3F },
41 { 0xFDB1, 0x01E3 },
42 { 0xFDB3, 0x0FFF },
43 { 0xF003, 0x08F0 },
44 { 0xF007, 0x3C3F },
45 { 0xF006, 0x0050 }
46};
47
48
49static const struct chip_helper_init_values init_vals_v22_v23[] = {
50 { 0xF81C, 0x00FF },
51
52 { 0xF80C, 0x1FFF },
53 { 0xFA25, 0x001F },
54 { 0xF804, 0x00FF },
55 { 0xF802, 0x0FFF },
56
57
58
59};
60
61static const u16 reset_program_a_v1_or_v2[] = {
62 0x0000
63};
64static const u16 reset_program_b_v1_or_v2[] = {
65 0x0010, 0xFE00, 0xA021, 0xFF00, 0x8111, 0x0009, 0x0CA4, 0x0114,
66 0x0280, 0x04F8, 0xFE00, 0x6F25, 0x06E0, 0x0010, 0xFC00, 0x0121,
67 0xFC00, 0x0225, 0xFE00, 0x7125, 0xFE00, 0x6D11, 0x03F0, 0xFE00,
68 0x6E25, 0x0008, 0x00E0
69};
70
71static const struct chip_helper_reset_values reset_program_v1_or_v2[] =
72{
73 {
74 MAKE_GP(REGISTERS, 0x000C),
75 nelem(reset_program_a_v1_or_v2),
76 reset_program_a_v1_or_v2
77 },
78 {
79 MAKE_GP(MAC_PMEM, 0x000000),
80 nelem(reset_program_b_v1_or_v2),
81 reset_program_b_v1_or_v2
82 }
83};
84
85static const struct chip_map_address_t unifi_map_address_v1_v2[] =
86{
87 { 0xFE9F, 0xFE7B },
88 { 0xFE9E, 0xFE78 },
89 { 0xFE9D, 0xFE7E },
90 { 0xFE91, 0xFE90 },
91 { 0xFE8D, 0xFE8C },
92};
93
94static const struct chip_map_address_t unifi_map_address_v22_v23[] =
95{
96 { 0xF8F9, 0xF8AC },
97 { 0xF8FA, 0xF8AD },
98 { 0xF8FB, 0xF8AE },
99 { 0xF830, 0xF81E },
100 { 0xF831, 0xF81F },
101 { 0xF8FC, 0xF8AF },
102};
103
104static const struct chip_device_regs_t unifi_device_regs_null =
105{
106 0xFE81,
107 0x0000,
108 0x0000,
109 {
110 0x0000,
111 0x0000,
112 0x0000,
113 0x0000,
114 0x0000,
115 0x0000
116 },
117 {
118 0x0000,
119 0x0000,
120 0x0000,
121 0x0000,
122 0x0000,
123 0x0000
124 },
125 0x0000,
126 0x0000,
127 0x0000,
128 0x0000,
129 0x0000,
130 0xFFE9,
131 0xFFEA,
132 0x0000,
133 0x0000,
134 0x0000,
135 0x0000,
136 0x0000,
137 0x0000,
138 0x0000,
139 0x0000,
140 0x0000,
141 0x0000
142};
143
144
145static const struct chip_device_regs_t unifi_device_regs_v1 =
146{
147 0xFE81,
148 0xFE87,
149 0xFE9C,
150 {
151 0xFE90,
152 0xFE8C,
153 0xFE7B,
154 0xFE78,
155 0xFE7E,
156 0x0000
157 },
158 {
159 0xFE91,
160 0xFE8D,
161 0xFE9F,
162 0xFE9E,
163 0xFE9D,
164 0x0000
165 },
166 0xFE92,
167 0x0001,
168 0xFDA0,
169 0x0000,
170 0xFE92,
171 0xFFE9,
172 0xFFEA,
173 0x0051,
174 0xFE70,
175 0xFE6B,
176 0xFE6A,
177 0xFE69,
178 0xFE68,
179 0xFE67,
180 0xFE65,
181 0xFDE9,
182 0x0000
183};
184
185
186static const struct chip_device_regs_t unifi_device_regs_v2 =
187{
188 0xFE81,
189 0xFE87,
190 0xFE9C,
191 {
192 0xFE90,
193 0xFE8C,
194 0xFE7B,
195 0xFE78,
196 0xFE7E,
197 0x0000
198 },
199 {
200 0xFE91,
201 0xFE8D,
202 0xFE9F,
203 0xFE9E,
204 0xFE9D,
205 0x0000
206 },
207 0xFE92,
208 0x0000,
209 0xFDE9,
210 0xFFFF,
211 0xFDE9,
212 0xFFE9,
213 0xFFEA,
214 0x0051,
215 0xFE70,
216 0xFE6B,
217 0xFE6A,
218 0xFE69,
219 0xFE68,
220 0xFE67,
221 0xFE65,
222 0xFE69,
223 0x0000
224};
225
226
227static const struct chip_device_regs_t unifi_device_regs_v22_v23 =
228{
229 0xFE81,
230 0xF84F,
231 0xF81D,
232 {
233 0xF81E,
234 0xF81F,
235 0xF8AC,
236 0xF8AD,
237 0xF8AE,
238 0xF8AF
239 },
240 {
241 0xF830,
242 0xF831,
243 0xF8F9,
244 0xF8FA,
245 0xF8FB,
246 0xF8FC
247 },
248 0xF82F,
249 0x0001,
250 0x0000,
251 0x0000,
252 0xF82F,
253 0xFFE9,
254 0xFFEA,
255 0x001B,
256 0x0055,
257 0xF84B,
258 0xF84C,
259 0xF84D,
260 0xF84E,
261 0xF92F,
262 0xF92B,
263 0xF84D,
264 0xF9FB
265};
266
267
268static const struct window_shift_info_t prog_window_array_unifi_v1_v2[CHIP_HELPER_WT_COUNT] =
269{
270 { TRUE, 11, 0x0200 },
271 { TRUE, 11, 0x0000 },
272 { TRUE, 11, 0x0400 },
273 { FALSE, 0, 0 },
274 { FALSE, 0, 0 }
275};
276
277
278static const struct window_shift_info_t shared_window_array_unifi_v1_v2[CHIP_HELPER_WT_COUNT] =
279{
280 { FALSE, 0, 0 },
281 { FALSE, 0, 0 },
282 { FALSE, 0, 0 },
283 { FALSE, 0, 0 },
284 { TRUE, 11, 0x0000 }
285};
286
287
288static const struct window_shift_info_t generic_window_array_unifi_v22_v23[CHIP_HELPER_WT_COUNT] =
289{
290 { TRUE, 11, 0x3800 },
291 { FALSE, 0, 0 },
292 { FALSE, 0, 0 },
293 { TRUE, 11, 0x2000 },
294 { TRUE, 11, 0x0000 }
295};
296
297
298static const struct window_info_t prog1_window_unifi_v1_v2 = { 0x0000, 0x2000, 0x0080, prog_window_array_unifi_v1_v2 };
299static const struct window_info_t prog2_window_unifi_v1_v2 = { 0x2000, 0x2000, 0x0000, prog_window_array_unifi_v1_v2 };
300static const struct window_info_t shared_window_unifi_v1_v2 = { 0x4000, 0x2000, 0x0000, shared_window_array_unifi_v1_v2 };
301
302
303static const struct window_info_t generic1_window_unifi_v22_v23 = { 0x0000, 0x2000, 0x0080, generic_window_array_unifi_v22_v23 };
304static const struct window_info_t generic2_window_unifi_v22_v23 = { 0x2000, 0x2000, 0x0000, generic_window_array_unifi_v22_v23 };
305static const struct window_info_t generic3_window_unifi_v22_v23 = { 0x4000, 0x2000, 0x0000, generic_window_array_unifi_v22_v23 };
306
307static const struct chip_device_desc_t chip_device_desc_null =
308{
309 { FALSE, 0x0000, 0x0000, 0x00 },
310 "",
311 "",
312 null_counted(),
313 null_counted(),
314 &unifi_device_regs_null,
315 {
316 FALSE,
317 FALSE,
318 FALSE,
319 FALSE,
320 FALSE,
321 },
322 null_counted(),
323
324 {
325 0x00000000,
326 0x00000000,
327 0x00000000,
328 0x00000000
329 },
330
331 {
332 0x0000
333 },
334
335 {
336 NULL,
337 NULL,
338 NULL
339 }
340};
341
342static const struct chip_device_desc_t unifi_device_desc_v1 =
343{
344 { FALSE, 0xf0ff, 0x1001, 0x01 },
345 "UF105x",
346 "UniFi-1",
347 counted(init_vals_v1),
348 counted(reset_program_v1_or_v2),
349 &unifi_device_regs_v1,
350 {
351 TRUE,
352 TRUE,
353 FALSE,
354 FALSE,
355 TRUE,
356 },
357 counted(unifi_map_address_v1_v2),
358
359 {
360 0x00100000,
361 0x00000000,
362 0x00000000,
363 0x00200000,
364 },
365
366 {
367 0x8000
368 },
369
370 {
371 &prog1_window_unifi_v1_v2,
372 &prog2_window_unifi_v1_v2,
373 &shared_window_unifi_v1_v2
374 }
375};
376
377static const struct chip_device_desc_t unifi_device_desc_v2 =
378{
379 { FALSE, 0xf0ff, 0x2001, 0x02 },
380 "UF2...",
381 "UniFi-2",
382 counted(init_vals_v2),
383 counted(reset_program_v1_or_v2),
384 &unifi_device_regs_v2,
385 {
386 TRUE,
387 TRUE,
388 FALSE,
389 FALSE,
390 TRUE,
391 },
392 counted(unifi_map_address_v1_v2),
393
394 {
395 0x00100000,
396 0x00000000,
397 0x00000000,
398 0x00200000,
399 },
400
401 {
402 0x8000
403 },
404
405 {
406 &prog1_window_unifi_v1_v2,
407 &prog2_window_unifi_v1_v2,
408 &shared_window_unifi_v1_v2
409 }
410};
411
412static const struct chip_device_desc_t unifi_device_desc_v3 =
413{
414 { FALSE, 0xf0ff, 0x3001, 0x02 },
415 "UF2...",
416 "UniFi-3",
417 counted(init_vals_v2),
418 counted(reset_program_v1_or_v2),
419 &unifi_device_regs_v2,
420 {
421 TRUE,
422 TRUE,
423 FALSE,
424 FALSE,
425 TRUE,
426 },
427 counted(unifi_map_address_v1_v2),
428
429 {
430 0x00100000,
431 0x00000000,
432 0x00000000,
433 0x00200000,
434 },
435
436 {
437 0x8000
438 },
439
440 {
441 &prog1_window_unifi_v1_v2,
442 &prog2_window_unifi_v1_v2,
443 &shared_window_unifi_v1_v2
444 }
445};
446
447static const struct chip_device_desc_t unifi_device_desc_v22 =
448{
449 { FALSE, 0x00ff, 0x0022, 0x07 },
450 "UF60xx",
451 "UniFi-4",
452 counted(init_vals_v22_v23),
453 null_counted(),
454 &unifi_device_regs_v22_v23,
455 {
456 FALSE,
457 FALSE,
458 TRUE,
459 FALSE,
460 TRUE,
461 },
462 counted(unifi_map_address_v22_v23),
463
464 {
465 0x00C00000,
466 0x00000000,
467 0x00000000,
468 0x00000000,
469 },
470
471 {
472 0x8000
473 },
474
475 {
476 &generic1_window_unifi_v22_v23,
477 &generic2_window_unifi_v22_v23,
478 &generic3_window_unifi_v22_v23
479 }
480};
481
482static const struct chip_device_desc_t unifi_device_desc_v23 =
483{
484 { FALSE, 0x00ff, 0x0023, 0x08 },
485 "UF....",
486 "UF.... (5)",
487 counted(init_vals_v22_v23),
488 null_counted(),
489 &unifi_device_regs_v22_v23,
490 {
491 FALSE,
492 FALSE,
493 TRUE,
494 TRUE,
495 TRUE,
496 },
497 counted(unifi_map_address_v22_v23),
498
499 {
500 0x00C00000,
501 0x00000000,
502 0x00000000,
503 0x00000000,
504 },
505
506 {
507 0x8000
508 },
509
510 {
511 &generic1_window_unifi_v22_v23,
512 &generic2_window_unifi_v22_v23,
513 &generic3_window_unifi_v22_v23
514 }
515};
516
517static const struct chip_device_desc_t hyd_wlan_subsys_desc_v1 =
518{
519 { FALSE, 0x00ff, 0x0044, 0x00 },
520 "HYD...",
521 "HYD... ",
522 counted(init_vals_v22_v23),
523 null_counted(),
524 &unifi_device_regs_v22_v23,
525 {
526 FALSE,
527 FALSE,
528 TRUE,
529 FALSE,
530 TRUE,
531 },
532 counted(unifi_map_address_v22_v23),
533
534 {
535 0x00C00000,
536 0x00000000,
537 0x00000000,
538 0x00000000,
539 },
540
541 {
542 0x8000
543 },
544
545 {
546 &generic1_window_unifi_v22_v23,
547 &generic2_window_unifi_v22_v23,
548 &generic3_window_unifi_v22_v23
549 }
550};
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568static const struct chip_device_desc_t *chip_ver_to_desc[] =
569{
570 &unifi_device_desc_v1,
571 &unifi_device_desc_v2,
572 &unifi_device_desc_v3,
573 &unifi_device_desc_v22,
574 &unifi_device_desc_v23,
575 &hyd_wlan_subsys_desc_v1
576};
577
578ChipDescript* ChipHelper_GetVersionSdio(u8 sdio_ver)
579{
580 u32 i;
581
582 for (i = 0; i < nelem(chip_ver_to_desc); i++)
583 {
584 if (chip_ver_to_desc[i]->chip_version.sdio == sdio_ver)
585 {
586 return chip_ver_to_desc[i];
587 }
588 }
589
590 return &chip_device_desc_null;
591}
592
593
594ChipDescript* ChipHelper_GetVersionAny(u16 from_FF9A, u16 from_FE81)
595{
596 u32 i;
597
598 if ((from_FF9A & 0xFF00) != 0)
599 {
600 for (i = 0; i < nelem(chip_ver_to_desc); i++)
601 {
602 if (chip_ver_to_desc[i]->chip_version.pre_bc7 &&
603 ((from_FF9A & chip_ver_to_desc[i]->chip_version.mask) ==
604 chip_ver_to_desc[i]->chip_version.result))
605 {
606 return chip_ver_to_desc[i];
607 }
608 }
609 }
610 else
611 {
612 for (i = 0; i < nelem(chip_ver_to_desc); i++)
613 {
614 if (!chip_ver_to_desc[i]->chip_version.pre_bc7 &&
615 ((from_FE81 & chip_ver_to_desc[i]->chip_version.mask) ==
616 chip_ver_to_desc[i]->chip_version.result))
617 {
618 return chip_ver_to_desc[i];
619 }
620 }
621 }
622
623 return &chip_device_desc_null;
624}
625
626
627ChipDescript* ChipHelper_GetVersionUniFi(u16 ver)
628{
629 return ChipHelper_GetVersionAny(0x0000, ver);
630}
631
632
633ChipDescript *ChipHelper_Null(void)
634{
635 return &chip_device_desc_null;
636}
637
638
639ChipDescript* ChipHelper_GetVersionBlueCore(enum chip_helper_bluecore_age bc_age, u16 version)
640{
641 if (bc_age == chip_helper_bluecore_pre_bc7)
642 {
643 return ChipHelper_GetVersionAny(version, 0x0000);
644 }
645 else
646 {
647 return ChipHelper_GetVersionAny(0x0000, version);
648 }
649}
650
651
652
653
654
655#define CHIP_HELPER_DEF0_C_DEF(ret_type, name, info) \
656 ret_type ChipHelper_ ## name(ChipDescript * chip_help) \
657 { \
658 return chip_help->info; \
659 }
660#define CHIP_HELPER_DEF1_C_DEF(ret_type, name, type1, name1)
661
662CHIP_HELPER_LIST(C_DEF)
663
664
665
666
667u16 ChipHelper_MapAddress_SPI2HOST(ChipDescript *chip_help, u16 addr)
668{
669 u32 i;
670 for (i = 0; i < chip_help->map.len; i++)
671 {
672 if (chip_help->map.vals[i].spi == addr)
673 {
674 return chip_help->map.vals[i].host;
675 }
676 }
677 return addr;
678}
679
680
681u16 ChipHelper_MapAddress_HOST2SPI(ChipDescript *chip_help, u16 addr)
682{
683 u32 i;
684 for (i = 0; i < chip_help->map.len; i++)
685 {
686 if (chip_help->map.vals[i].host == addr)
687 {
688 return chip_help->map.vals[i].spi;
689 }
690 }
691 return addr;
692}
693
694
695
696
697
698
699
700
701u16 ChipHelper_WINDOW_ADDRESS(ChipDescript *chip_help,
702 enum chip_helper_window_index window)
703{
704 if (window < CHIP_HELPER_WINDOW_COUNT &&
705 chip_help->windows[window] != NULL)
706 {
707 return chip_help->windows[window]->address + chip_help->windows[window]->blocked;
708 }
709 return 0;
710}
711
712
713
714u16 ChipHelper_WINDOW_SIZE(ChipDescript *chip_help,
715 enum chip_helper_window_index window)
716{
717 if (window < CHIP_HELPER_WINDOW_COUNT &&
718 chip_help->windows[window] != NULL)
719 {
720 return chip_help->windows[window]->size - chip_help->windows[window]->blocked;
721 }
722 return 0;
723}
724
725
726
727
728u32 ChipHelper_ClockStartupSequence(ChipDescript *chip_help,
729 const struct chip_helper_init_values **val)
730{
731 *val = chip_help->init.vals;
732 return chip_help->init.len;
733}
734
735
736
737u32 ChipHelper_HostResetSequence(ChipDescript *chip_help,
738 const struct chip_helper_reset_values **val)
739{
740 *val = chip_help->reset_prog.vals;
741 return chip_help->reset_prog.len;
742}
743
744
745
746s32 ChipHelper_DecodeWindow(ChipDescript *chip_help,
747 enum chip_helper_window_index window,
748 enum chip_helper_window_type type,
749 u32 offset,
750 u16 *page, u16 *addr, u32 *len)
751{
752 const struct window_info_t *win;
753 const struct window_shift_info_t *mode;
754 u16 of, pg;
755
756 if (window >= CHIP_HELPER_WINDOW_COUNT)
757 {
758 return FALSE;
759 }
760 if ((win = chip_help->windows[window]) == NULL)
761 {
762 return FALSE;
763 }
764 if (type >= CHIP_HELPER_WT_COUNT)
765 {
766 return FALSE;
767 }
768 if ((mode = &win->mode[type]) == NULL)
769 {
770 return FALSE;
771 }
772 if (!mode->allowed)
773 {
774 return FALSE;
775 }
776
777 pg = (u16)(offset >> mode->page_shift) + mode->page_offset;
778 of = (u16)(offset & ((1 << mode->page_shift) - 1));
779
780
781
782 while (of < win->blocked)
783 {
784 of += 1 << mode->page_shift;
785 pg--;
786 }
787 *page = pg;
788 *addr = win->address + of;
789 *len = win->size - of;
790 return TRUE;
791}
792
793
794